diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4e703fe1a3..e61b1cfc6d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -19,6 +19,9 @@ Test fixtures for use by clients are available for each release on the [Github r - ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948)) - ✨ [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Remove delegation behavior of EXTCODE* ([#984](https://github.com/ethereum/execution-spec-tests/pull/984)) - ✨ [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004)) +- 🔀 Update EIP-7251 according to [spec updates](https://github.com/ethereum/EIPs/pull/9127) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024)). +- 🔀 Update EIP-7002 according to [spec updates](https://github.com/ethereum/EIPs/pull/9119) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024)). +- 🔀 Update EIP-2935 according to [spec updates](https://github.com/ethereum/EIPs/pull/9144) ([#1046](https://github.com/ethereum/execution-spec-tests/pull/1046)) ### 🛠️ Framework @@ -65,8 +68,6 @@ Test fixtures for use by clients are available for each release on the [Github r - ✨ Add a default location for evm logs (`--evm-dump-dir`) when filling tests ([#999](https://github.com/ethereum/execution-spec-tests/pull/999)). - ✨ Slow tests now have greater timeout when making a request to the T8N server ([#1037](https://github.com/ethereum/execution-spec-tests/pull/1037)). - ✨ Introduce [`pytest.mark.parametrize_by_fork`](https://ethereum.github.io/execution-spec-tests/main/writing_tests/test_markers/#pytestmarkfork_parametrize) helper marker ([#1019](https://github.com/ethereum/execution-spec-tests/pull/1019), [#1057](https://github.com/ethereum/execution-spec-tests/pull/1057)). -- 🔀 Update EIP-7251 according to [spec updates](https://github.com/ethereum/EIPs/pull/9127) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024)). -- 🔀 Update EIP-7002 according to [spec updates](https://github.com/ethereum/EIPs/pull/9119) ([#1024](https://github.com/ethereum/execution-spec-tests/pull/1024)). - 🐞 fix(consume): allow absolute paths with `--evm-bin` ([#1052](https://github.com/ethereum/execution-spec-tests/pull/1052)). ### 🔧 EVM Tools diff --git a/src/ethereum_test_forks/forks/contracts/history_contract.bin b/src/ethereum_test_forks/forks/contracts/history_contract.bin index 84b6d9f386..b135cf2c69 100644 Binary files a/src/ethereum_test_forks/forks/contracts/history_contract.bin and b/src/ethereum_test_forks/forks/contracts/history_contract.bin differ diff --git a/src/ethereum_test_forks/forks/forks.py b/src/ethereum_test_forks/forks/forks.py index 5e8c90185f..3be81f3120 100644 --- a/src/ethereum_test_forks/forks/forks.py +++ b/src/ethereum_test_forks/forks/forks.py @@ -986,7 +986,7 @@ def system_contracts(cls, block_number: int = 0, timestamp: int = 0) -> List[Add Address(0x00000000219AB540356CBB839CBE05303D7705FA), Address(0x0C15F14308530B7CDB8460094BBB9CC28B9AAAAA), Address(0x00431F263CE400F4455C2DCF564E53007CA4BBBB), - Address(0x0AAE40965E6800CD9B1F4B05FF21581047E3F91E), + Address(0x0F792BE4B0C0CB4DAE440EF133E90C0ECD48CCCC), ] + super(Prague, cls).system_contracts(block_number, timestamp) @classmethod @@ -1126,7 +1126,7 @@ def pre_allocation_blockchain(cls) -> Mapping: with open(CURRENT_FOLDER / "contracts" / "history_contract.bin", mode="rb") as f: new_allocation.update( { - 0x0AAE40965E6800CD9B1F4B05FF21581047E3F91E: { + 0x0F792BE4B0C0CB4DAE440EF133E90C0ECD48CCCC: { "nonce": 1, "code": f.read(), } diff --git a/tests/prague/eip2935_historical_block_hashes_from_state/contract_deploy_tx.json b/tests/prague/eip2935_historical_block_hashes_from_state/contract_deploy_tx.json new file mode 100644 index 0000000000..cfb28514a2 --- /dev/null +++ b/tests/prague/eip2935_historical_block_hashes_from_state/contract_deploy_tx.json @@ -0,0 +1,15 @@ +{ + "type": "0x0", + "nonce": "0x0", + "to": null, + "gas": "0x3d090", + "gasPrice": "0xe8d4a51000", + "maxPriorityFeePerGas": null, + "maxFeePerGas": null, + "value": "0x0", + "input": "0x60538060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500", + "v": "0x1b", + "r": "0x539", + "s": "0xbaefe09f0109759", + "hash": "0x8c7bd2d3713a0b2bb693463d2a78c4d612ac47dd38ecb74f8996a4b6fc96f03c" +} \ No newline at end of file diff --git a/tests/prague/eip2935_historical_block_hashes_from_state/spec.py b/tests/prague/eip2935_historical_block_hashes_from_state/spec.py index ba13f6c5c1..0a709547cd 100644 --- a/tests/prague/eip2935_historical_block_hashes_from_state/spec.py +++ b/tests/prague/eip2935_historical_block_hashes_from_state/spec.py @@ -11,7 +11,7 @@ class ReferenceSpec: version: str -ref_spec_2935 = ReferenceSpec("EIPS/eip-2935.md", "68d54a80a4f5b9c0cf4ae3a10586d63ef221de36") +ref_spec_2935 = ReferenceSpec("EIPS/eip-2935.md", "a04da454a5a6ba86a87bb9e15f811feaff3c849a") @dataclass(frozen=True) @@ -22,6 +22,6 @@ class Spec: """ FORK_TIMESTAMP = 15_000 - HISTORY_STORAGE_ADDRESS = 0x0AAE40965E6800CD9B1F4B05FF21581047E3F91E - HISTORY_SERVE_WINDOW = 8192 + HISTORY_STORAGE_ADDRESS = 0x0F792BE4B0C0CB4DAE440EF133E90C0ECD48CCCC + HISTORY_SERVE_WINDOW = 8191 BLOCKHASH_OLD_WINDOW = 256 diff --git a/tests/prague/eip2935_historical_block_hashes_from_state/test_block_hashes.py b/tests/prague/eip2935_historical_block_hashes_from_state/test_block_hashes.py index 6e0ff09ddd..090764aca9 100644 --- a/tests/prague/eip2935_historical_block_hashes_from_state/test_block_hashes.py +++ b/tests/prague/eip2935_historical_block_hashes_from_state/test_block_hashes.py @@ -311,9 +311,9 @@ def test_block_hashes_history( @pytest.mark.parametrize( "block_number,reverts", [ - pytest.param(1, False, id="current_block"), - pytest.param(2, False, id="future_block"), - pytest.param(2**64 - 1, False, id="2**64-1"), + pytest.param(1, True, id="current_block"), + pytest.param(2, True, id="future_block"), + pytest.param(2**64 - 1, True, id="2**64-1"), pytest.param(2**64, True, id="2**64"), ], ) @@ -337,13 +337,24 @@ def test_invalid_history_contract_calls( returned_block_hash_slot = storage.store_next(0) block_hash_opcode_slot = storage.store_next(0) + return_offset = 64 + return_size = 32 + args_size = 32 + # Check the first block outside of the window if any code = ( Op.MSTORE(0, block_number) + Op.SSTORE( - return_code_slot, Op.CALL(Op.GAS, Spec.HISTORY_STORAGE_ADDRESS, 0, 0, 32, 32, 64) + return_code_slot, + Op.CALL( + address=Spec.HISTORY_STORAGE_ADDRESS, + args_offset=0, + args_size=args_size, + ret_offset=return_offset, + ret_size=return_size, + ), ) - + Op.SSTORE(returned_block_hash_slot, Op.MLOAD(32)) + + Op.SSTORE(returned_block_hash_slot, Op.MLOAD(return_offset)) + Op.SSTORE(block_hash_opcode_slot, Op.BLOCKHASH(block_number)) ) check_contract_address = pre.deploy_contract(code, storage=storage.canary()) @@ -364,3 +375,63 @@ def test_invalid_history_contract_calls( post=post, reverts=reverts, ) + + +@pytest.mark.parametrize( + "args_size,reverts", + [ + pytest.param(0, True, id="zero_size"), + pytest.param(33, True, id="too_large"), + pytest.param(31, True, id="too_small"), + ], +) +@pytest.mark.valid_from("Prague") +def test_invalid_history_contract_calls_input_size( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + reverts: bool, + args_size: int, +): + """Test calling the history contract with invalid input sizes.""" + storage = Storage() + + return_code_slot = storage.store_next(not reverts) + returned_block_hash_slot = storage.store_next(0) + + return_offset = 64 + return_size = 32 + block_number = 0 + + # Check the first block outside of the window if any + code = ( + Op.MSTORE(0, block_number) + + Op.SSTORE( + return_code_slot, + Op.CALL( + address=Spec.HISTORY_STORAGE_ADDRESS, + args_offset=0, + args_size=args_size, + ret_offset=return_offset, + ret_size=return_size, + ), + ) + + Op.SSTORE(returned_block_hash_slot, Op.MLOAD(return_offset)) + ) + check_contract_address = pre.deploy_contract(code, storage=storage.canary()) + + txs = [ + Transaction( + to=check_contract_address, + gas_limit=10_000_000, + sender=pre.fund_eoa(), + ) + ] + post = {check_contract_address: Account(storage=storage)} + + blocks = [Block(txs=txs)] + blockchain_test( + pre=pre, + blocks=blocks, + post=post, + reverts=reverts, + ) diff --git a/tests/prague/eip2935_historical_block_hashes_from_state/test_contract_deployment.py b/tests/prague/eip2935_historical_block_hashes_from_state/test_contract_deployment.py new file mode 100644 index 0000000000..5aff02cdfa --- /dev/null +++ b/tests/prague/eip2935_historical_block_hashes_from_state/test_contract_deployment.py @@ -0,0 +1,26 @@ +""" +abstract: Tests [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935). + Test system contract deployment for [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935). +""" # noqa: E501 + +from os.path import realpath +from pathlib import Path + +from ethereum_test_forks import Prague +from ethereum_test_tools import Address, generate_system_contract_deploy_test + +from .spec import Spec, ref_spec_2935 + +REFERENCE_SPEC_GIT_PATH = ref_spec_2935.git_path +REFERENCE_SPEC_VERSION = ref_spec_2935.version + + +@generate_system_contract_deploy_test( + fork=Prague, + tx_json_path=Path(realpath(__file__)).parent / "contract_deploy_tx.json", + expected_deploy_address=Address(Spec.HISTORY_STORAGE_ADDRESS), + expected_system_contract_storage=None, +) +def test_system_contract_deployment(*args, **kwargs): + """Verify deployment of the block hashes system contract.""" + yield from [] diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py index 5f898cde56..bb54fa6806 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py @@ -2654,7 +2654,7 @@ def test_set_code_to_system_contract( ) caller_payload = consolidation_request.calldata call_value = consolidation_request.value - case Address(0x0AAE40965E6800CD9B1F4B05FF21581047E3F91E): # EIP-2935 + case Address(0x0F792BE4B0C0CB4DAE440EF133E90C0ECD48CCCC): # EIP-2935 caller_payload = Hash(0) caller_code_storage[call_return_data_size_slot] = 32 case _: