From 93d90a3627c0ec5be209a87a3b2cdf51f21812dc Mon Sep 17 00:00:00 2001 From: pdobacz <5735525+pdobacz@users.noreply.github.com> Date: Wed, 25 Sep 2024 13:22:27 +0200 Subject: [PATCH] new(tests): EOF - EIP-6206: clarify "non-returning instruction" --- ...ion.py => test_nonreturning_validation.py} | 40 ++++++++++++++++++- tests/prague/eip7692_eof_v1/tracker.md | 12 +++--- 2 files changed, 44 insertions(+), 8 deletions(-) rename tests/prague/eip7692_eof_v1/eip6206_jumpf/{test_nonretruning_validation.py => test_nonreturning_validation.py} (69%) diff --git a/tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py b/tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py similarity index 69% rename from tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py rename to tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py index 766ae717c4..80f4afbfe1 100644 --- a/tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py +++ b/tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py @@ -7,7 +7,7 @@ from ethereum_test_tools import EOFException, EOFTestFiller from ethereum_test_tools.eof.v1 import Container, Section from ethereum_test_tools.vm.opcode import Opcodes as Op -from ethereum_test_types.eof.v1 import NON_RETURNING_SECTION +from ethereum_test_types.eof.v1 import NON_RETURNING_SECTION, ContainerKind from ethereum_test_vm import Bytecode from .. import EOF_FORK_NAME @@ -47,11 +47,17 @@ def test_first_section_returning(eof_test: EOFTestFiller, code_section: Section) pytest.param(Section.Code(Op.PUSH0 + Op.STOP, code_outputs=1), id="stop1"), pytest.param(Section.Code(Op.INVALID, code_outputs=0), id="invalid0"), pytest.param(Section.Code(Op.PUSH0 + Op.INVALID, code_outputs=1), id="invalid1"), + pytest.param(Section.Code(Op.RETURN(0, 0), code_outputs=0), id="return0"), + pytest.param(Section.Code(Op.PUSH0 + Op.RETURN(0, 0), code_outputs=1), id="return1"), + pytest.param(Section.Code(Op.REVERT(0, 0), code_outputs=0), id="revert0"), + pytest.param(Section.Code(Op.PUSH0 + Op.REVERT(0, 0), code_outputs=1), id="revert1"), + pytest.param(Section.Code(Op.RJUMP[-3], code_outputs=0), id="rjump0"), + pytest.param(Section.Code(Op.PUSH0 + Op.RJUMP[-3], code_outputs=1), id="rjump1"), ], ) def test_returning_section_not_returning(eof_test: EOFTestFiller, code_section: Section): """ - Test EOF validation failing because a returning sections ends with non-returning instruction. + Test EOF validation failing because a returning section has no RETF or JUMPF-to-returning. """ eof_test( data=Container( @@ -60,6 +66,36 @@ def test_returning_section_not_returning(eof_test: EOFTestFiller, code_section: code_section, ], validity_error=EOFException.INVALID_NON_RETURNING_FLAG, + ), + ) + + +@pytest.mark.parametrize( + "code_section", + [ + pytest.param( + Section.Code(Op.RETURNCONTRACT[0](0, 0), code_outputs=0), id="returncontract0" + ), + pytest.param( + Section.Code(Op.PUSH0 + Op.RETURNCONTRACT[0](0, 0), code_outputs=1), + id="returncontract1", + ), + ], +) +def test_returning_section_returncontract(eof_test: EOFTestFiller, code_section: Section): + """ + Test EOF validation failing because a returning section has no RETF or JUMPF-to-returning - + RETURNCONTRACT version + """ + eof_test( + data=Container( + sections=[ + Section.Code(Op.CALLF[1] + Op.INVALID, max_stack_height=code_section.code_outputs), + code_section, + ] + + [Section.Container(Container.Code(Op.INVALID))], + validity_error=EOFException.INVALID_NON_RETURNING_FLAG, + kind=ContainerKind.INITCODE, ) ) diff --git a/tests/prague/eip7692_eof_v1/tracker.md b/tests/prague/eip7692_eof_v1/tracker.md index 5af2f0c03b..7554fde5ac 100644 --- a/tests/prague/eip7692_eof_v1/tracker.md +++ b/tests/prague/eip7692_eof_v1/tracker.md @@ -266,7 +266,7 @@ - [ ] RETF reached via different paths (ethereum/tests: src/EOFTestsFiller/efStack/retf_stack_validation_Copier.json) - [ ] RETF in variable stack segment is not allowed (ethereum/tests: src/EOFTestsFiller/efStack/retf_variable_stack_Copier.json) - [ ] Extra items on stack allowed for terminating instructions other than RETF (ethereum/tests: src/EOFTestsFiller/EIP5450/validInvalidFiller.yml) -- [x] Invalid RETF in a non-returning function (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_first_section_returning_code`) +- [x] Invalid RETF in a non-returning function (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_first_section_returning_code`) #### JUMPF @@ -278,7 +278,7 @@ - [ ] JUMPF into function with fewer outputs than current one (ethereum/tests: src/EOFTestsFiller/efStack/jumpf_to_returning_Copier.json) - [ ] Extra items on stack are allowed for JUMPF to returning function (ethereum/tests: src/EOFTestsFiller/efStack/jumpf_to_returning_Copier.json) - [ ] JUMPF to returning in a variable stack segment is not allowed (ethereum/tests: src/EOFTestsFiller/efStack/jumpf_to_returning_variable_stack_Copier.json) -- [x] Invalid JUMPF in a non-returning function (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_retf_in_nonreturning`) +- [x] Invalid JUMPF in a non-returning function (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_retf_in_nonreturning`) #### Stack overflow @@ -333,19 +333,19 @@ ### Validation -- [x] Zero section returning (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_first_section_returning` ethereum/tests: ./src/EOFTestsFiller/efExample/validInvalidFiller.yml src/EOFTestsFiller/EIP4750/validInvalidFiller.yml) -- [x] Zero section declared non-returning but ends with RETF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_retf_in_nonreturning` ethereum/tests: src/EOFTestsFiller/EIP4750/validInvalidFiller.yml) +- [x] Zero section returning (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_first_section_returning` ethereum/tests: ./src/EOFTestsFiller/efExample/validInvalidFiller.yml src/EOFTestsFiller/EIP4750/validInvalidFiller.yml) +- [x] Zero section declared non-returning but ends with RETF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_retf_in_nonreturning` ethereum/tests: src/EOFTestsFiller/EIP4750/validInvalidFiller.yml) - [ ] CALLF into non-returning function (ethereum/tests: src/EOFTestsFiller/efValidation/callf_into_nonreturning_Copier.json) - [ ] Valid JUMPF into sections with equal number of outputs (ethereum/tests: src/EOFTestsFiller/efValidation/jumpf_equal_outputs_Copier.json) - [ ] Valid JUMPF into sections with different but compatible number of outputs (ethereum/tests: src/EOFTestsFiller/efValidation/jumpf_compatible_outputs_Copier.json) - [ ] JUMPF into sections with incompatible outputs (ethereum/tests: src/EOFTestsFiller/efValidation/jumpf_incompatible_outputs_Copier.json) - [ ] Non-returning section without JUMPF (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) -- [x] Non-returning section with JUMPF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_jumpf_in_nonreturning` ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) +- [x] Non-returning section with JUMPF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_jumpf_in_nonreturning` ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] Returning section with RETF (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] Returning section with JUMPF (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] Returning section with JUMPF to returning and RETF (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] Returning section with JUMPF to non-returning and RETF (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) -- [x] Returning section without JUMPF nor RETF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonretruning_validation.py::test_returning_section_not_returning`) +- [x] Returning section without JUMPF nor RETF (`tests/prague/eip7692_eof_v1/eip6206_jumpf/test_nonreturning_validation.py::test_returning_section_not_returning`) - [ ] Invalid non-returning flag (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] Circular JUMPF between two sections (ethereum/tests: src/EOFTestsFiller/efValidation/non_returning_status_Copier.json) - [ ] JUMPF into non-existing section