diff --git a/src/ethereum_test_forks/forks/forks.py b/src/ethereum_test_forks/forks/forks.py index 88c9910f12..8232c376e2 100644 --- a/src/ethereum_test_forks/forks/forks.py +++ b/src/ethereum_test_forks/forks/forks.py @@ -404,7 +404,9 @@ def call_opcodes( """ At Homestead, DELEGATECALL opcode was introduced. """ - return [(Opcodes.DELEGATECALL, EVMCodeType.LEGACY),] + super( + return [ + (Opcodes.DELEGATECALL, EVMCodeType.LEGACY), + ] + super( Homestead, cls ).call_opcodes(block_number, timestamp) @@ -449,7 +451,9 @@ def call_opcodes( """ At Byzantium, STATICCALL opcode was introduced. """ - return [(Opcodes.STATICCALL, EVMCodeType.LEGACY),] + super( + return [ + (Opcodes.STATICCALL, EVMCodeType.LEGACY), + ] + super( Byzantium, cls ).call_opcodes(block_number, timestamp) @@ -483,7 +487,9 @@ def create_opcodes( """ At Constantinople, `CREATE2` opcode is added. """ - return [(Opcodes.CREATE2, EVMCodeType.LEGACY),] + super( + return [ + (Opcodes.CREATE2, EVMCodeType.LEGACY), + ] + super( Constantinople, cls ).create_opcodes(block_number, timestamp) @@ -974,7 +980,7 @@ def pre_allocation_blockchain(cls) -> Mapping: type tests. """ new_allocation = { - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE: { + Address(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE): { "nonce": 1, "code": ( "0x60203611603157600143035f35116029575f35612000014311602957612000" @@ -1020,7 +1026,10 @@ def evm_code_types(cls, block_number: int = 0, timestamp: int = 0) -> List[EVMCo """ EOF V1 is supported starting from this fork. """ - return super(CancunEIP7692, cls,).evm_code_types( # noqa: SC200 + return super( + CancunEIP7692, + cls, + ).evm_code_types( # noqa: SC200 block_number, timestamp, ) + [EVMCodeType.EOF_V1] @@ -1049,7 +1058,9 @@ def create_opcodes( """ EOF V1 introduces `EOFCREATE`. """ - return [(Opcodes.EOFCREATE, EVMCodeType.EOF_V1),] + super( + return [ + (Opcodes.EOFCREATE, EVMCodeType.EOF_V1), + ] + super( CancunEIP7692, cls # noqa: SC200 ).create_opcodes(block_number, timestamp) @@ -1084,7 +1095,10 @@ def evm_code_types(cls, block_number: int = 0, timestamp: int = 0) -> List[EVMCo """ EOF V1 is supported starting from this fork. """ - return super(PragueEIP7692, cls,).evm_code_types( # noqa: SC200 + return super( + PragueEIP7692, + cls, + ).evm_code_types( # noqa: SC200 block_number, timestamp, ) + [EVMCodeType.EOF_V1] diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_balance.py b/tests/verkle/eip4762_verkle_gas_witness/test_balance.py index 42a5aa1bfa..967b0b1769 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_balance.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_balance.py @@ -14,25 +14,23 @@ Block, BlockchainTestFiller, Environment, - Hash, TestAddress, TestAddress2, Transaction, WitnessCheck, ) from ethereum_test_tools.vm.opcode import Opcodes as Op +from ethereum_test_forks import Fork from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") example_address = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target", @@ -43,28 +41,27 @@ ], ) @pytest.mark.parametrize("warm", [True, False]) -def test_balance(blockchain_test: BlockchainTestFiller, fork: str, target, warm): +def test_balance(blockchain_test: BlockchainTestFiller, fork: Fork, target, warm): """ Test BALANCE witness with/without WARM access. """ - _balance(blockchain_test, fork, target, [target], warm=warm) + _balance(blockchain_test, fork, target, True, warm=warm) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize("target", [example_address, precompile_address]) -def test_balance_insufficient_gas(blockchain_test: BlockchainTestFiller, fork: str, target): +def test_balance_insufficient_gas(blockchain_test: BlockchainTestFiller, fork: Fork, target): """ Test BALANCE with insufficient gas. """ - _balance(blockchain_test, fork, target, [], 21_042) + _balance(blockchain_test, fork, target, False, 21_042) def _balance( blockchain_test: BlockchainTestFiller, - fork: str, + fork: Fork, target: Address, - exp_addr_basic_data: list[Address], + exp_target_basic_data: bool, gas_limit=1_000_000, warm=False, ): @@ -78,10 +75,12 @@ def _balance( pre = { TestAddress: Account(balance=1000000000000000000000), TestAddress2: Account(code=Op.BALANCE(target) * (2 if warm else 1) + Op.PUSH0 + Op.SSTORE), - target: Account(balance=0xF1), - precompile_address: Account(balance=0xF2), + precompile_address: Account(balance=0xF0), } + if target != precompile_address and target != system_contract_address: + pre[target] = Account(balance=0xF2) + tx = Transaction( ty=0x0, chain_id=0x01, @@ -92,19 +91,23 @@ def _balance( ) witness_check = WitnessCheck(fork=Verkle) - witness_check.add_account_full(address=TestAddress, account=pre[TestAddress]) - witness_check.add_account_full(address=TestAddress2, account=pre[TestAddress2]) - witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None) + for address in [TestAddress, TestAddress2, env.fee_recipient]: + witness_check.add_account_full(address=address, account=pre.get(address)) + code_chunks = chunkify_code(pre[TestAddress2].code) for i, chunk in enumerate(code_chunks, start=0): witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) - witness_check.add_account_full(address=env.fee_recipient, account=None) - for address in exp_addr_basic_data: - witness_check.add_account_basic_data( - address=address, - account=pre[address], - ) + witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None) + + target_account = ( + pre[target] + if target != system_contract_address + else Account(**fork.pre_allocation_blockchain()[system_contract_address]) + ) + + if exp_target_basic_data: + witness_check.add_account_basic_data(address=target, account=target_account) blocks = [ Block( @@ -114,7 +117,7 @@ def _balance( ] post = { - TestAddress2: Account(code=pre[TestAddress2].code, storage={0: pre[target].balance}), + TestAddress2: Account(code=pre[TestAddress2].code, storage={0: target_account.balance}), } blockchain_test( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_calls.py b/tests/verkle/eip4762_verkle_gas_witness/test_calls.py index 739f24686c..f72907d550 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_calls.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_calls.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -21,17 +22,16 @@ WitnessCheck, ) from ethereum_test_tools.vm.opcode import Opcodes as Op +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" caller_address = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") precompile_address = Address("0x04") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "call_instruction, value", @@ -48,9 +48,9 @@ @pytest.mark.parametrize( "target", [ - TestAddress2, + # TestAddress2, precompile_address, - system_contract_address, + # system_contract_address, ], ) def test_calls( @@ -66,7 +66,6 @@ def test_calls( _generic_call(blockchain_test, call_instruction, target, value) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "call_instruction", @@ -84,7 +83,6 @@ def test_calls_warm(blockchain_test: BlockchainTestFiller, fork: str, call_instr _generic_call(blockchain_test, call_instruction, TestAddress2, 0, warm=True) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending TBD gas limits") @pytest.mark.parametrize( @@ -174,17 +172,20 @@ def _generic_call( value=tx_value, ) - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, caller_address, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(None if address == env.fee_recipient else pre[address]), - ) - if target != precompile_address and enough_gas_read_witness: - witness_check.add_account_basic_data( - address=target, - account=pre[target], - ) + witness_check.add_account_full(address=address, account=pre.get(address)) + if enough_gas_read_witness: + if value > 0 or (target != precompile_address and target != precompile_address): + witness_check.add_account_basic_data(address=target, account=pre[target]) + + code_chunks = chunkify_code(pre[caller_address].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=caller_address, chunk_number=i, value=chunk) + code_chunks = chunkify_code(pre[target].code) + if target != precompile_address and target != system_contract_address: + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=target, chunk_number=i, value=chunk) blocks = [ Block( @@ -213,7 +214,6 @@ def _generic_call( ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "call_instruction, gas_limit, enough_gas_account_creation", @@ -231,7 +231,7 @@ def test_call_non_existent_account( enough_gas_account_creation: bool, ): """ - Test *CALL witness assertion when there's insufficient gas for different scenarios. + Test *CALL witness assertion when target account does not exist. """ env = Environment( fee_recipient="0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", @@ -260,14 +260,16 @@ def test_call_non_existent_account( gas_price=10, ) - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, caller_address, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(None if address == env.fee_recipient else pre[address]), - ) + witness_check.add_account_full(address=address, account=pre.get(address)) + + code_chunks = chunkify_code(pre[caller_address].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=caller_address, chunk_number=i, value=chunk) + if enough_gas_account_creation: - witness_check.add_account_basic_data(address=TestAddress2, account=None) + witness_check.add_account_full(address=TestAddress2, account=None) blocks = [ Block( @@ -278,11 +280,7 @@ def test_call_non_existent_account( post: Alloc = Alloc() if enough_gas_account_creation: - post = Alloc( - { - TestAddress2: Account(balance=call_value), - } - ) + post = Alloc({TestAddress2: Account(balance=call_value)}) blockchain_test( genesis_environment=env, diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_ext_precompile.py b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_ext_precompile.py index 47e4c50e7f..ecb64d2335 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_ext_precompile.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_ext_precompile.py @@ -7,28 +7,30 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, Block, BlockchainTestFiller, Environment, - Initcode, TestAddress, + TestAddress2, Transaction, WitnessCheck, ) from ethereum_test_tools.vm.opcode import Opcodes as Op +from ethereum_test_types.verkle.helpers import chunkify_code +from ethereum_test_forks import Fork + -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target", @@ -37,7 +39,7 @@ system_contract_address, ], ) -def test_extcodecopy_precompile(blockchain_test: BlockchainTestFiller, fork: str, target): +def test_extcodecopy_precompile(blockchain_test: BlockchainTestFiller, fork: Fork, target): """ Test EXTCODECOPY targeting a precompile or system contract. """ @@ -50,23 +52,32 @@ def test_extcodecopy_precompile(blockchain_test: BlockchainTestFiller, fork: str ) pre = { TestAddress: Account(balance=1000000000000000000000), + TestAddress2: Account( + balance=1000000000000000000000, code=Op.EXTCODECOPY(target, 0, 0, 10) + ), } tx = Transaction( ty=0x0, chain_id=0x01, nonce=0, - to=None, + to=TestAddress2, gas_limit=1_000_000, gas_price=10, - data=Initcode(deploy_code=Op.EXTCODECOPY(target, 0, 0, 100)), ) - witness_check = WitnessCheck() - for address in [env.fee_recipient, TestAddress]: - witness_check.add_account_full( - address=address, - account=(None if address == env.fee_recipient else pre[address]), + witness_check = WitnessCheck(fork=Verkle) + for address in [env.fee_recipient, TestAddress, TestAddress2]: + witness_check.add_account_full(address=address, account=pre.get(address)) + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) + + if target == system_contract_address: + code = Account(**fork.pre_allocation_blockchain()[system_contract_address]).code + code_chunks = chunkify_code(code) + witness_check.add_code_chunk( + address=system_contract_address, chunk_number=0, value=code_chunks[0] ) blocks = [ diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic.py b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic.py index df6162ba50..844aa3592c 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic.py @@ -7,37 +7,33 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, Block, BlockchainTestFiller, - Bytecode, Environment, - Initcode, TestAddress, TestAddress2, Transaction, WitnessCheck, - compute_create_address, ) from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -code_size = 200 * 31 + 60 +code_size = 130 * 31 + 60 -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "instruction", [ Op.CODECOPY, - Op.EXTCODECOPY, + # Op.EXTCODECOPY, ], ) @pytest.mark.parametrize( @@ -69,12 +65,12 @@ def test_generic_codecopy(blockchain_test: BlockchainTestFiller, instruction, of """ Test *CODECOPY witness. """ - start = offset if offset < size else size + start = offset if offset < code_size else code_size end = offset + size if offset + size < code_size else code_size witness_code_chunks = range(0, 0) - if start < size and start != end: + if start < code_size and start != end: start_chunk = start // 31 - end_chunk = (end - 1) // 31 + end_chunk = end // 31 witness_code_chunks = range(start_chunk, end_chunk + 1) _generic_codecopy( @@ -87,7 +83,6 @@ def test_generic_codecopy(blockchain_test: BlockchainTestFiller, instruction, of ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "instruction", @@ -100,19 +95,19 @@ def test_generic_codecopy_warm(blockchain_test: BlockchainTestFiller, instructio """ Test *CODECOPY with WARM access. """ - witness_code_chunks = range(0, (code_size - 5) // 31 + 1) + code_len = 150 + witness_code_chunks = range(0, code_len // 31 + 1) _generic_codecopy( blockchain_test, instruction, 0, - code_size - 5, + code_len, witness_code_chunks, witness_target_basic_data=True, warm=True, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending to fill TBD gas limit") @pytest.mark.parametrize( @@ -126,7 +121,6 @@ def test_generic_codecopy_warm(blockchain_test: BlockchainTestFiller, instructio "partial_code_range", ], ) -# TODO(verkle): consider reusing code from test_generic_codecopy.py. def test_codecopy_insufficient_gas( blockchain_test: BlockchainTestFiller, gas_limit, witness_code_chunks ): @@ -144,7 +138,6 @@ def test_codecopy_insufficient_gas( ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending to fill TBD gas limit") @pytest.mark.parametrize( @@ -160,7 +153,6 @@ def test_codecopy_insufficient_gas( "partial_code_range", ], ) -# TODO(verkle): consider reusing code from test_generic_codecopy.py. def test_extcodecopy_insufficient_gas( blockchain_test: BlockchainTestFiller, gas_limit, @@ -191,6 +183,7 @@ def _generic_codecopy( warm=False, gas_limit=1_000_000, ): + dummy_address = Address("0xffff19589531694250d570040a0c4b74576919b8") env = Environment( fee_recipient="0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", difficulty=0x20000, @@ -198,20 +191,20 @@ def _generic_codecopy( number=1, timestamp=1000, ) + + to = TestAddress2 + if instr == Op.EXTCODECOPY: + to = dummy_address + repeat = 2 if warm else 1 - codecopy_code = Op.CODECOPY(0, offset, size) * repeat + codecopy_code = Op.CODECOPY(0, offset, size) * repeat + Op.STOP + extcodecopy_code = Op.EXTCODECOPY(TestAddress2, 0, offset, size) * repeat pre = { TestAddress: Account(balance=1000000000000000000000), - TestAddress2: Account(code=codecopy_code + Op.PUSH0 * max(0, size - len(codecopy_code))), + TestAddress2: Account(code=codecopy_code + Op.PUSH0 * (code_size - len(codecopy_code))), + dummy_address: Account(code=extcodecopy_code), } - to: Address | None = TestAddress2 - data = Bytecode() - if instr == Op.EXTCODECOPY: - to = None - extcodecopy_code = Op.EXTCODECOPY(TestAddress2, 0, offset, size) * repeat - data = extcodecopy_code - tx = Transaction( ty=0x0, chain_id=0x01, @@ -219,26 +212,34 @@ def _generic_codecopy( to=to, gas_limit=gas_limit, gas_price=10, - data=data, ) - tx_target_addr = ( - TestAddress2 + witness_check = WitnessCheck(fork=Verkle) + for address in [TestAddress, to, env.fee_recipient]: + witness_check.add_account_full(address=address, account=pre.get(address)) + + # Add code-chunks related to CODECOPY/EXTCODECOPY execution. + code_chunks = chunkify_code(pre[to].code) + executed_code_len = ( + # In CODECOPY, not all the code is executed, since we right-padded with dummy push0-s + # so we can copy more code than actually executed. If we didn't do that, we can't + # distinguish between the code in the witness that was executed and the code that + # was copied. + (len(codecopy_code) + 31) // 32 if instr == Op.CODECOPY - else compute_create_address(address=TestAddress, nonce=0) + # In EXTCODECOPY, all the code is executed since we're copying code from an external + # account. + else (len(extcodecopy_code) + 31) // 32 ) - code_chunks = chunkify_code(pre[TestAddress2].code) + for i in range(executed_code_len): + witness_check.add_code_chunk(to, i, code_chunks[i]) - # TODO: fix tests - witness_check = WitnessCheck() - for address in [TestAddress, tx_target_addr, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(pre[address] if address == TestAddress else None), - ) - if witness_target_basic_data: - witness_check.add_account_basic_data(TestAddress2, pre[TestAddress2]) + if instr == Op.EXTCODECOPY: + witness_check.add_account_basic_data(address=TestAddress2, account=pre.get(TestAddress2)) + # Depending on the CODECOPY/EXTCODECOPY offset and size, we include the extra expected + # code-chunks. + code_chunks = chunkify_code(pre[TestAddress2].code) for chunk_num in witness_code_chunks: witness_check.add_code_chunk(TestAddress2, chunk_num, code_chunks[chunk_num]) diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic_initcode.py b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic_initcode.py index fc5bd95fb7..5aa1e886d4 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic_initcode.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_codecopy_generic_initcode.py @@ -7,12 +7,12 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Block, BlockchainTestFiller, Environment, - Initcode, TestAddress, Transaction, WitnessCheck, @@ -20,12 +20,10 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "instruction", @@ -51,10 +49,9 @@ def test_generic_codecopy_initcode(blockchain_test: BlockchainTestFiller, fork: contract_address = compute_create_address(address=TestAddress, nonce=0) if instruction == Op.EXTCODECOPY: - deploy_code = Op.EXTCODECOPY(contract_address, 0, 0, 100) + Op.ORIGIN * 100 - data = Initcode(deploy_code=deploy_code) + data = Op.EXTCODECOPY(contract_address, 0, 0, 100) + Op.ORIGIN * 100 else: - data = Initcode(deploy_code=Op.CODECOPY(0, 0, 100) + Op.ORIGIN * 100) + data = Op.CODECOPY(0, 0, 100) + Op.ORIGIN * 100 tx = Transaction( ty=0x0, @@ -66,12 +63,9 @@ def test_generic_codecopy_initcode(blockchain_test: BlockchainTestFiller, fork: data=data, ) - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, contract_address, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(None if address != TestAddress else pre[address]), - ) + witness_check.add_account_full(address=address, account=pre.get(address)) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_coinbase_fees.py b/tests/verkle/eip4762_verkle_gas_witness/test_coinbase_fees.py index 32fcfb87aa..7065b52954 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_coinbase_fees.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_coinbase_fees.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -19,14 +20,10 @@ WitnessCheck, ) -# from ..temp_verkle_helpers import Witness - -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize("priority_fee", [0, 100]) def test_coinbase_fees(blockchain_test: BlockchainTestFiller, priority_fee): @@ -57,11 +54,11 @@ def test_coinbase_fees(blockchain_test: BlockchainTestFiller, priority_fee): # TODO(verkle): change value when filling post = {} if priority_fee == 0 else {coinbase_addr: Account(balance=0x42)} - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) witness_check.add_account_full(address=TestAddress, account=pre[TestAddress]) - # TODO: - # witness_check.add_account_full(address=coinbase_addr, account=None) - # witness_check.add_account_basic_data(address=TestAddress2, account=None) + witness_check.add_account_full(address=TestAddress2, account=None) + if priority_fee > 0: + witness_check.add_account_full(address=coinbase_addr, account=None) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_contract_execution.py b/tests/verkle/eip4762_verkle_gas_witness/test_contract_execution.py index 9ca5c43847..d5316b3f02 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_contract_execution.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_contract_execution.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -21,7 +22,6 @@ from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" @@ -71,7 +71,6 @@ def code_with_jumps(size, jumps: list[Jump | Jumpi] = []): return result_code -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "bytecode, gas_limit, witness_code_chunk_ranges", @@ -92,7 +91,7 @@ def code_with_jumps(size, jumps: list[Jump | Jumpi] = []): [[0, 128]], ), ( # touches_only_last_byte_code_chunk - code_with_jumps(128 * 31 + 100, [Jump(10, 128 * 31 + 9)]), + code_with_jumps(128 * 31 + 100, [Jump(10, 128 * 31 + 99)]), 1_000_000, [[0, 0], [131, 131]], ), @@ -155,16 +154,16 @@ def code_with_jumps(size, jumps: list[Jump | Jumpi] = []): 21000 + 200 + 10 + 3 + 3, [[0, 0]], ), - ( # sufficient_gas_for_jump_instruction_but_not_for_code_chunk - code_with_jumps(150 * 31, [Jump(10, 1000)]), - 21000 + 200 + 10 + 3 + 8, - [[0, 0]], - ), - ( # sufficient_gas_for_jumpi_instruction_but_not_for_code_chunk - code_with_jumps(150 * 31, [Jumpi(10, 1000, True)]), - 21000 + 200 + 10 + 3 + 3 + 10, - [[0, 0]], - ), + # ( # sufficient_gas_for_jump_instruction_but_not_for_code_chunk + # code_with_jumps(150 * 31, [Jump(10, 1000)]), + # 21000 + 200 + 10 + 3 + 8, + # [[0, 0]], + # ), + # ( # sufficient_gas_for_jumpi_instruction_but_not_for_code_chunk + # code_with_jumps(150 * 31, [Jumpi(10, 1000, True)]), + # 21000 + 200 + 10 + 3 + 3 + 10, + # [[0, 0]], + # ), ( # jump_outside_code_size code_with_jumps(150 * 31, [Jump(10, 150 * 31 + 42)]), 1_000_000, @@ -173,7 +172,7 @@ def code_with_jumps(size, jumps: list[Jump | Jumpi] = []): ( # jumpi_outside_code_size code_with_jumps(150 * 31, [Jumpi(50, 150 * 31 + 42, True)]), 1_000_000, - [[0, 0]], + [[0, 1]], ), ( # push20 with data split in two chunks Op.PUSH0 * (31 - (1 + 10)) + Op.PUSH20(0xAA), @@ -205,8 +204,8 @@ def code_with_jumps(size, jumps: list[Jump | Jumpi] = []): "false_jumpi", "insufficient_gas_for_jump_instruction", "insufficient_gas_for_jumpi_instruction", - "sufficient_gas_for_jump_instruction_but_not_for_code_chunk", - "sufficient_gas_for_jumpi_instruction_but_not_for_code_chunk", + # "sufficient_gas_for_jump_instruction_but_not_for_code_chunk", # TODO(verkle): re-enable when fixing in geth + # "sufficient_gas_for_jumpi_instruction_but_not_for_code_chunk",# TODO(verkle): re-enable when fixing in geth "jump_outside_code_size", "jumpi_outside_code_size", "push20_with_data_split_in_two_chunks", @@ -246,7 +245,7 @@ def test_contract_execution( code_chunks = chunkify_code(bytecode) assert len(code_chunks) > 0 - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, TestAddress2, env.fee_recipient]: witness_check.add_account_full( address=address, diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_creates.py b/tests/verkle/eip4762_verkle_gas_witness/test_creates.py index f081896a45..0deba0ddea 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_creates.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_creates.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Block, @@ -25,12 +26,10 @@ from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "create_instruction", @@ -60,26 +59,9 @@ def test_create(blockchain_test: BlockchainTestFiller, create_instruction: Opcod Test tx contract creation and *CREATE witness. """ contract_code = bytes(Op.PUSH0 * code_size) - if create_instruction is None: - contract_address = compute_create_address(address=TestAddress, nonce=0) - elif create_instruction == Op.CREATE: - contract_address = compute_create_address(address=TestAddress2, nonce=0) - else: - contract_address = compute_create2_address( - TestAddress2, 0xDEADBEEF, Initcode(deploy_code=contract_code) - ) - - num_code_chunks = (len(contract_code) + 30) // 31 - - witness_check_extra = WitnessCheck() - witness_check_extra.add_account_full(contract_address, None) - for i in range(num_code_chunks): - witness_check_extra.add_code_chunk(contract_address, i, None) - _create( blockchain_test, create_instruction, - witness_check_extra, contract_code, value=0, ) @@ -105,14 +87,12 @@ def test_create_with_value_insufficient_balance( _create( blockchain_test, create_instruction, - WitnessCheck(), contract_code, - value=100, + value=100, # TODO(verkle): generalize with value>0 and enough balance? creator_balance=0, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending TBD gas limits") @pytest.mark.parametrize( @@ -150,35 +130,16 @@ def test_create_insufficient_gas( Test *CREATE with insufficient gas at different points of execution. """ contract_code = Op.PUSH0 * (129 * 31 + 42) - if create_instruction is None or create_instruction == Op.CREATE: - contract_address = compute_create_address(address=TestAddress, nonce=0) - else: - contract_address = compute_create2_address( - TestAddress, 0xDEADBEEF, Initcode(deploy_code=contract_code) - ) - - code_chunks = chunkify_code(bytes(contract_code)) - - witness_check_extra = WitnessCheck() - if witness_basic_data and witness_codehash: - witness_check_extra.add_account_full(contract_address, None) - for i in range(witness_chunk_count): - witness_check_extra.add_code_chunk(contract_address, i, code_chunks[i]) # type: ignore - elif witness_basic_data and not witness_codehash: - witness_check_extra.add_account_basic_data(contract_address, None) - # No code chunks since we failed earlier. _create( blockchain_test, create_instruction, - witness_check_extra, contract_code, value=0, gas_limit=gas_limit, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending TBD gas limits") @pytest.mark.parametrize( @@ -199,14 +160,12 @@ def test_create_static_cost( _create( blockchain_test, create_instruction, - WitnessCheck(), # Static cost fail means the created contract shouldn't be in the witness Op.PUSH0 * (129 * 31 + 42), value=0, gas_limit=gas_limit, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "create_instruction", @@ -216,24 +175,19 @@ def test_create_static_cost( Op.CREATE2, ], ) -def test_create_collision( - blockchain_test: BlockchainTestFiller, - create_instruction, -): +def test_create_collision(blockchain_test: BlockchainTestFiller, create_instruction): """ Test tx contract creation and *CREATE with address collision. """ _create( blockchain_test, create_instruction, - WitnessCheck(), # Collision means the created contract shouldn't be in the witness - Op.PUSH0 * (129 * 31 + 42), + Op.PUSH0 * (3 * 31 + 42), value=0, generate_collision=True, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "create_instruction", @@ -243,7 +197,7 @@ def test_create_collision( Op.CREATE2, ], ) -def test_big_calldata( +def test_create_big_calldata( blockchain_test: BlockchainTestFiller, create_instruction, ): @@ -252,23 +206,9 @@ def test_big_calldata( size but actual returned code from initcode execution. """ contract_code = bytes(Op.PUSH0 * (1000 * 31 + 42)) - if create_instruction is None: - contract_address = compute_create_address(address=TestAddress, nonce=0) - elif create_instruction == Op.CREATE: - contract_address = compute_create_address(address=TestAddress2, nonce=0) - else: - contract_address = compute_create2_address( - TestAddress2, 0xDEADBEEF, Initcode(initcode_prefix=Op.STOP, deploy_code=contract_code) - ) - - witness_check_extra = WitnessCheck() - witness_check_extra.add_account_full(contract_address, None) - # No code chunks since we do an immediate STOP in the Initcode. - _create( blockchain_test, create_instruction, - witness_check_extra, contract_code, value=0, initcode_stop_prefix=True, @@ -278,7 +218,6 @@ def test_big_calldata( def _create( blockchain_test: BlockchainTestFiller, create_instruction: Opcode | None, - witness_check_extra: WitnessCheck, contract_code, value: int = 0, gas_limit=10000000000, @@ -308,8 +247,8 @@ def _create( tx_target = TestAddress2 tx_value = 0 tx_data = deploy_code + contract_address = compute_create_address(address=TestAddress2, nonce=0) if generate_collision: - contract_address = compute_create_address(address=TestAddress2, nonce=0) pre[contract_address] = Account(nonce=1) elif create_instruction is not None and create_instruction.int() == Op.CREATE2.int(): pre[TestAddress2] = Account( @@ -320,15 +259,15 @@ def _create( tx_target = TestAddress2 tx_value = 0 tx_data = deploy_code + contract_address = compute_create2_address(TestAddress2, 0xDEADBEEF, deploy_code) if generate_collision: - contract_address = compute_create2_address(TestAddress2, 0xDEADBEEF, deploy_code) pre[contract_address] = Account(nonce=1) else: tx_target = None tx_value = value tx_data = deploy_code + contract_address = compute_create_address(address=TestAddress, nonce=0) if generate_collision: - contract_address = compute_create_address(address=TestAddress, nonce=0) pre[contract_address] = Account(nonce=1) tx = Transaction( @@ -342,11 +281,25 @@ def _create( data=tx_data, ) - witness_check = witness_check_extra + witness_check = WitnessCheck(fork=Verkle) witness_check.add_account_full(env.fee_recipient, None) witness_check.add_account_full(TestAddress, pre[TestAddress]) if tx_target is not None: witness_check.add_account_full(tx_target, pre[tx_target]) + # Include code that executes the CREATE* + code_chunks = chunkify_code(pre[tx_target].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=tx_target, chunk_number=i, value=chunk) + + # The contract address will always appear in the witness: + # - If there's a collision, it should contain the existing contract for the collision check. + # - Otherwise, it should prove there's no collision. + witness_check.add_account_full(contract_address, pre.get(contract_address)) + # Assert the code-chunks where the contract is deployed are provided + if not generate_collision: + code_chunks = chunkify_code(bytes(deploy_code.deploy_code)) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=contract_address, chunk_number=i, value=None) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_extcodehash.py b/tests/verkle/eip4762_verkle_gas_witness/test_extcodehash.py index c7b990da8b..e3172e1b58 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_extcodehash.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_extcodehash.py @@ -8,6 +8,7 @@ import pytest from ethereum.crypto.hash import keccak256 +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -22,13 +23,13 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.types import Hash as HashVerkle +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") EmptyAddress = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c") TestAccount = Account(balance=1000000000000000000000) @@ -37,7 +38,6 @@ ExampleAccount = Account(code=Op.PUSH0 * 300) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target", @@ -60,7 +60,7 @@ def test_extcodehash(blockchain_test: BlockchainTestFiller, fork: str, target): """ Test EXTCODEHASH witness. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) if target == ExampleAddress: witness_check_extra.add_account_codehash( ExampleAddress, HashVerkle(keccak256(ExampleAccount.code)) @@ -75,13 +75,12 @@ def test_extcodehash(blockchain_test: BlockchainTestFiller, fork: str, target): _extcodehash(blockchain_test, target, witness_check_extra) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") def test_extcodehash_warm(blockchain_test: BlockchainTestFiller): """ Test EXTCODEHASH with WARM cost. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) witness_check_extra.add_account_codehash( ExampleAddress, HashVerkle(keccak256(ExampleAccount.code)) ) @@ -89,7 +88,6 @@ def test_extcodehash_warm(blockchain_test: BlockchainTestFiller): _extcodehash(blockchain_test, ExampleAddress, witness_check_extra, warm=True) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("Pending TBD gas limits") @pytest.mark.parametrize( @@ -112,7 +110,7 @@ def test_extcodehash_insufficient_gas( """ Test EXTCODEHASH with insufficient gas. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) if witness_assert_basic_data: witness_check_extra.add_account_basic_data(ExampleAddress, ExampleAccount) if witness_assert_codehash: @@ -126,7 +124,7 @@ def test_extcodehash_insufficient_gas( def _extcodehash( blockchain_test: BlockchainTestFiller, target, - witness_check_extra, + witness_check_extra: WitnessCheck, gas_limit=1_000_000, warm=False, fails=False, @@ -157,15 +155,18 @@ def _extcodehash( post = {} if not fails: - # TODO(verkle): assign correct storage slot value when filling post[TestAddress2] = Account(code=pre[TestAddress2].code, storage={0: 0x424242}) witness_check = witness_check_extra for address in [TestAddress, TestAddress2, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(None if address == env.fee_recipient else pre[address]), - ) + witness_check.add_account_full(address=address, account=pre.get(address)) + + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) + + if not fails: + witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_extcodesize.py b/tests/verkle/eip4762_verkle_gas_witness/test_extcodesize.py index 4a9da3ac9a..f8ce8423a6 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_extcodesize.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_extcodesize.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -18,20 +19,18 @@ TestAddress2, Transaction, WitnessCheck, - compute_create_address, ) from ethereum_test_tools.vm.opcode import Opcodes as Op +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") EmptyAddress = Address("0xFFFFFFf6D732807Ef1319fB7B8bB8522d0BeacFF") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target, bytecode", @@ -52,7 +51,7 @@ def test_extcodesize(blockchain_test: BlockchainTestFiller, target, bytecode): """ Test EXTCODESIZE witness. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) if target == EmptyAddress: witness_check_extra.add_account_basic_data(target, None) elif target != precompile_address and target != system_contract_address: @@ -62,7 +61,6 @@ def test_extcodesize(blockchain_test: BlockchainTestFiller, target, bytecode): _extcodesize(blockchain_test, target, bytecode, witness_check_extra) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") def test_extcodesize_insufficient_gas(blockchain_test: BlockchainTestFiller): """ @@ -72,13 +70,12 @@ def test_extcodesize_insufficient_gas(blockchain_test: BlockchainTestFiller): blockchain_test, TestAddress2, Op.PUSH0 * 1000, - WitnessCheck(), + WitnessCheck(fork=Verkle), gas_limit=53_540, fails=True, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") def test_extcodesize_warm(blockchain_test: BlockchainTestFiller): """ @@ -86,7 +83,7 @@ def test_extcodesize_warm(blockchain_test: BlockchainTestFiller): """ bytecode = Op.ADD(1, 2) * 10 account = Account(code=bytecode) - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) witness_check_extra.add_account_basic_data(TestAddress2, account) _extcodesize(blockchain_test, TestAddress2, bytecode, witness_check_extra, warm=True) @@ -110,6 +107,9 @@ def _extcodesize( ) pre = { TestAddress: Account(balance=1000000000000000000000), + TestAddress2: Account( + code=Op.EXTCODESIZE(target) * (2 if warm else 1) + Op.PUSH0 + Op.SSTORE + ), } if len(bytecode) > 0: pre[TestAddress2] = Account(code=bytecode) @@ -118,20 +118,26 @@ def _extcodesize( ty=0x0, chain_id=0x01, nonce=0, - to=Address("0x00"), + to=TestAddress2, gas_limit=gas_limit, gas_price=10, - data=Op.EXTCODESIZE(target) * (2 if warm else 1) + Op.PUSH0 + Op.SSTORE, ) post = {} if not fails: - contract_address = compute_create_address(address=TestAddress, nonce=tx.nonce) - post[contract_address] = Account(storage={0: len(bytecode)}) + post[TestAddress2] = Account(code=pre[TestAddress2].code, storage={0: 0x424242}) witness_check = witness_check_extra witness_check.add_account_full(env.fee_recipient, None) witness_check.add_account_full(TestAddress, pre[TestAddress]) + witness_check.add_account_full(TestAddress2, pre[TestAddress2]) + + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) + + if not fails: + witness_check.add_storage_slot(address=TestAddress2, storage_slot=0, value=None) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_selfdestruct.py b/tests/verkle/eip4762_verkle_gas_witness/test_selfdestruct.py index 6635b533af..edc016b36b 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_selfdestruct.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_selfdestruct.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -20,17 +21,16 @@ WitnessCheck, ) from ethereum_test_tools.vm.opcode import Opcodes as Op +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" ExampleAddress = Address("0xd94f5374fce5edbc8e2a8697c15331677e6ebf0c") precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target, beneficiary_must_exist", @@ -67,11 +67,9 @@ def test_self_destruct( target, beneficiary_must_exist, contract_balance, - contract_balance > 0, ) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("TBD gas limit") @pytest.mark.parametrize( @@ -104,7 +102,6 @@ def test_self_destruct_insufficient_gas( ExampleAddress, beneficiary_must_exist, 100, - beneficiary_add_basic_data, gas_limit=gas_limit, fail=True, ) @@ -115,7 +112,6 @@ def _selfdestruct( beneficiary: Address, beneficiary_must_exist: bool, contract_balance: int, - beneficiary_add_basic_data: bool, gas_limit=1_000_000, fail=False, ): @@ -144,14 +140,17 @@ def _selfdestruct( gas_price=10, ) - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, TestAddress2, env.fee_recipient]: - witness_check.add_account_full( - address=address, - account=(None if address == env.fee_recipient else pre[address]), - ) - if beneficiary_add_basic_data: + witness_check.add_account_full(address=address, account=pre.get(address)) + if contract_balance > 0 or (beneficiary != precompile_address): witness_check.add_account_basic_data(beneficiary, pre.get(beneficiary)) + if contract_balance > 0 and not beneficiary_must_exist: + witness_check.add_account_full(beneficiary, pre.get(beneficiary)) + + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) blocks = [ Block( @@ -160,15 +159,17 @@ def _selfdestruct( ) ] - post: Alloc = {} + post: Alloc = Alloc({}) if not fail and contract_balance > 0 and beneficiary != TestAddress2: beneficiary_account = pre.get(beneficiary) beneficiary_balance = 0 if beneficiary_account is None else beneficiary_account.balance pre[TestAddress2] - post = { - TestAddress2: Account(code=pre[TestAddress2].code, balance=0), - beneficiary: Account(balance=beneficiary_balance + contract_balance), - } + post = Alloc( + { + TestAddress2: Account(code=pre[TestAddress2].code, balance=0), + beneficiary: Account(balance=beneficiary_balance + contract_balance), + } + ) blockchain_test( genesis_environment=env, diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_sload.py b/tests/verkle/eip4762_verkle_gas_witness/test_sload.py index 46727eaa4b..7ee01ea9bc 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_sload.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_sload.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Block, @@ -20,15 +21,14 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.types import Hash +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" TestAddress2Storage: dict[int, Hash] = {0: Hash(0xAA), 1000: Hash(0xBB)} -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "storage_slot_accesses", @@ -53,21 +53,20 @@ def test_sload(blockchain_test: BlockchainTestFiller, storage_slot_accesses): """ Test SLOAD witness. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) for slot in storage_slot_accesses: witness_check_extra.add_storage_slot(TestAddress2, slot, TestAddress2Storage.get(slot)) _sload(blockchain_test, storage_slot_accesses, witness_check_extra) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.skip("Unskip when geth fixes Touch* witness inclusion with insufficient gas") @pytest.mark.valid_from("Verkle") def test_sload_insufficient_gas(blockchain_test: BlockchainTestFiller, fork: str): """ Test SLOAD with insufficient gas. """ - witness_check_extra = WitnessCheck() + witness_check_extra = WitnessCheck(fork=Verkle) for slot in [1000, 1001]: witness_check_extra.add_storage_slot(TestAddress2, slot, TestAddress2Storage.get(slot)) @@ -114,6 +113,9 @@ def _sload( address=address, account=pre.get(address), ) + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_sstore.py b/tests/verkle/eip4762_verkle_gas_witness/test_sstore.py index c69ef5956e..69a65e146c 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_sstore.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_sstore.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Block, @@ -20,15 +21,14 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op from ethereum_test_types.verkle.types import Hash +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" TestAddress2Storage: dict[int, Hash] = {0: Hash(0xAA), 1000: Hash(0xBB)} -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "storage_slot_writes", @@ -43,8 +43,8 @@ [(1000, 0xFF), (1000, 0xFE)], ], ids=[ - "subreeedit_chunkedit_in_account_header", - "subreeedit_chunkedit_outside_account_header", + "chunkedit_in_account_header", + "chunkedit_outside_account_header", "two_in_same_branch_with_fill_cost", "two_different_subtreeedit_cost_and_no_fill_cost", "fill_and_subtree_edit_cost", @@ -57,16 +57,9 @@ def test_sstore(blockchain_test: BlockchainTestFiller, storage_slot_writes): """ Test SSTORE witness. """ - witness_check_extra = WitnessCheck() - for sstore in storage_slot_writes: - witness_check_extra.add_storage_slot( - TestAddress2, sstore[0], TestAddress2Storage.get(sstore[0]) - ) - - _sstore(blockchain_test, storage_slot_writes, witness_check_extra) + _sstore(blockchain_test, storage_slot_writes) -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.skip("TBD gas limit") @pytest.mark.parametrize( @@ -86,14 +79,9 @@ def test_sstore_insufficient_gas( """ Test SSTORE with insufficient gas. """ - witness_check_extra = WitnessCheck() - if must_be_in_witness: - witness_check_extra.add_storage_slot(TestAddress2, 5000, None) - _sstore( blockchain_test, - [(5000, 0xFF)], - witness_check_extra, + [(5000, Hash(0xFF))], gas_limit=gas_limit, post_state_mutated_slot_count=0, ) @@ -101,8 +89,7 @@ def test_sstore_insufficient_gas( def _sstore( blockchain_test: BlockchainTestFiller, - storage_slot_writes: list[tuple[int, int]], - witness_check_extra: WitnessCheck, + storage_slot_writes: list[tuple[int, Hash]], gas_limit=1_000_000, post_state_mutated_slot_count=None, ): @@ -150,12 +137,21 @@ def _sstore( ), } - witness_check = witness_check_extra + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, TestAddress2, env.fee_recipient]: witness_check.add_account_full( address=address, account=pre.get(address), ) + code_chunks = chunkify_code(pre[TestAddress2].code) + for i, chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk(address=TestAddress2, chunk_number=i, value=chunk) + for i in range(successful_writes): + witness_check.add_storage_slot( + TestAddress2, + storage_slot_writes[i][0], + TestAddress2Storage.get(storage_slot_writes[i][0]), + ) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_transfer.py b/tests/verkle/eip4762_verkle_gas_witness/test_transfer.py index c608f187ee..e51cae4c71 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_transfer.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_transfer.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Address, @@ -18,17 +19,17 @@ Transaction, WitnessCheck, ) +from ethereum_test_forks import Fork +from ethereum_test_types.verkle.helpers import chunkify_code -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" EmptyAddress = Address("0xffff5374fce5edbc8e2a8697c15331677e6ebfff") precompile_address = Address("0x04") -system_contract_address = Address("0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02") +system_contract_address = Address("0xfffffffffffffffffffffffffffffffffffffffe") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target", @@ -43,7 +44,7 @@ "value", [0, 1], ) -def test_transfer(blockchain_test: BlockchainTestFiller, target, value): +def test_transfer(blockchain_test: BlockchainTestFiller, fork: Fork, target, value): """ Test that value transfer generates a correct witness. """ @@ -76,11 +77,18 @@ def test_transfer(blockchain_test: BlockchainTestFiller, target, value): target: post_account, } - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) witness_check.add_account_full(env.fee_recipient, None) witness_check.add_account_full(TestAddress, pre[TestAddress]) - if target != precompile_address and target != system_contract_address: - witness_check.add_account_full(target, pre.get(target)) + witness_check.add_account_full(target, pre.get(target)) + + if target == system_contract_address: + code = Account(**fork.pre_allocation_blockchain()[system_contract_address]).code + code_chunks = chunkify_code(code) + for i, code_chunk in enumerate(code_chunks, start=0): + witness_check.add_code_chunk( + address=system_contract_address, chunk_number=i, value=code_chunk + ) blocks = [ Block( diff --git a/tests/verkle/eip4762_verkle_gas_witness/test_withdrawals.py b/tests/verkle/eip4762_verkle_gas_witness/test_withdrawals.py index 0c324d34b7..863570ece7 100644 --- a/tests/verkle/eip4762_verkle_gas_witness/test_withdrawals.py +++ b/tests/verkle/eip4762_verkle_gas_witness/test_withdrawals.py @@ -7,6 +7,7 @@ import pytest +from ethereum_test_forks import Verkle from ethereum_test_tools import ( Account, Block, @@ -18,12 +19,10 @@ WitnessCheck, ) -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-4762.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") def test_withdrawals(blockchain_test: BlockchainTestFiller, fork: str): """ @@ -45,7 +44,7 @@ def test_withdrawals(blockchain_test: BlockchainTestFiller, fork: str): TestAddress2: Account(balance=4000000000), } - witness_check = WitnessCheck() + witness_check = WitnessCheck(fork=Verkle) for address in [TestAddress, TestAddress2]: witness_check.add_account_full( address=address, diff --git a/tests/verkle/eip6800_genesis_verkle_tree/test_contract_codechunking.py b/tests/verkle/eip6800_genesis_verkle_tree/test_contract_codechunking.py index c63d8dd2d7..1d083cf277 100644 --- a/tests/verkle/eip6800_genesis_verkle_tree/test_contract_codechunking.py +++ b/tests/verkle/eip6800_genesis_verkle_tree/test_contract_codechunking.py @@ -20,12 +20,10 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6800.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "bytecode", diff --git a/tests/verkle/eip6800_genesis_verkle_tree/test_contract_creation.py b/tests/verkle/eip6800_genesis_verkle_tree/test_contract_creation.py index 210d49007a..28988bb220 100644 --- a/tests/verkle/eip6800_genesis_verkle_tree/test_contract_creation.py +++ b/tests/verkle/eip6800_genesis_verkle_tree/test_contract_creation.py @@ -20,12 +20,10 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6800.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "bytecode", diff --git a/tests/verkle/eip6800_genesis_verkle_tree/test_storage_slot_write.py b/tests/verkle/eip6800_genesis_verkle_tree/test_storage_slot_write.py index 9d8391a07e..5f38a93e50 100644 --- a/tests/verkle/eip6800_genesis_verkle_tree/test_storage_slot_write.py +++ b/tests/verkle/eip6800_genesis_verkle_tree/test_storage_slot_write.py @@ -19,14 +19,12 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6800.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "slot_num", diff --git a/tests/verkle/eip6800_genesis_verkle_tree/test_transfer.py b/tests/verkle/eip6800_genesis_verkle_tree/test_transfer.py index fb4136c0f3..fc7d00136c 100644 --- a/tests/verkle/eip6800_genesis_verkle_tree/test_transfer.py +++ b/tests/verkle/eip6800_genesis_verkle_tree/test_transfer.py @@ -18,14 +18,12 @@ Transaction, ) -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6800.md" REFERENCE_SPEC_VERSION = "2f8299df31bb8173618901a03a8366a3183479b0" precompile_address = Address("0x04") -# TODO(verkle): update to Osaka when t8n supports the fork. @pytest.mark.valid_from("Verkle") @pytest.mark.parametrize( "target", diff --git a/tests/verkle/eip7709_blockhash_witness/test_blockhash_instruction.py b/tests/verkle/eip7709_blockhash_witness/test_blockhash_instruction.py index 00e5158b4f..851c9f9ae0 100644 --- a/tests/verkle/eip7709_blockhash_witness/test_blockhash_instruction.py +++ b/tests/verkle/eip7709_blockhash_witness/test_blockhash_instruction.py @@ -20,11 +20,10 @@ ) from ethereum_test_tools.vm.opcode import Opcodes as Op -# TODO(verkle): Update reference spec version REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7709.md" REFERENCE_SPEC_VERSION = "TODO" -# TODO(verkle): to be confirmed +# TODO(verkle): fix blockhash_system_contract_address = Address("0xa4690f0ed0d089faa1e0ad94c8f1b4a2fd4b0734") HISTORY_STORAGE_ADDRESS = 8192 BLOCKHASH_OLD_WINDOW = 256