From e7dbdb94fc4b00ffe7558a2872a575d764c10cbe Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Fri, 4 Aug 2023 16:10:23 +0200 Subject: [PATCH] Add tests for JUMPF validation --- test/unittests/eof_validation_test.cpp | 127 +++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/test/unittests/eof_validation_test.cpp b/test/unittests/eof_validation_test.cpp index 509d2b252c..23f640c849 100644 --- a/test/unittests/eof_validation_test.cpp +++ b/test/unittests/eof_validation_test.cpp @@ -876,3 +876,130 @@ TEST(eof_validation, non_returning_status) validate_eof("EF0001 010008 02000200010007 040000 00 0080000001800001 00 E10001E4E50000"), EOFValidationError::invalid_non_returning_flag); } + +TEST(eof_validation, jumpf_equal_outputs) +{ + const auto code = + bytecode{"ef0001 01000c 020003 0004 0003 0004 040000 00 00800003 00030000 00030003"_hex} + + OP_CALLF + "0001" + OP_STOP + OP_JUMPF + "0002" + 3 * OP_PUSH0 + OP_RETF; + + EXPECT_EQ(validate_eof(code), EOFValidationError::success); +} + +TEST(eof_validation, jumpf_compatible_outputs) +{ + const auto code = + bytecode{"ef0001 01000c 020003 0004 0005 0004 040000 00 00800005 00050002 00030003"_hex} + + OP_CALLF + "0001" + OP_STOP + 2 * OP_PUSH0 + OP_JUMPF + "0002" + 3 * OP_PUSH0 + OP_RETF; + + EXPECT_EQ(validate_eof(code), EOFValidationError::success); +} + +TEST(eof_validation, jumpf_incompatible_outputs) +{ + const auto code = + bytecode{"ef0001 01000c 020003 0004 0005 0004 040000 00 00800003 00030002 00050003"_hex} + + OP_CALLF + "0001" + OP_STOP + OP_JUMPF + "0002" + 5 * OP_PUSH0 + OP_RETF; + + EXPECT_EQ(validate_eof(code), EOFValidationError::jumpf_destination_incompatible_outputs); +} + +TEST(eof_validation, jumpf_into_nonreturning_stack_validation) +{ + // Exactly required inputs on stack at JUMPF + EXPECT_EQ( + validate_eof("EF0001 010008 02000200060001 040000 00 0080000303800003 5F5F5FE50001 00"), + EOFValidationError::success); + + // Extra items on stack at JUMPF + EXPECT_EQ( + validate_eof("EF0001 010008 02000200070001 040000 00 0080000403800003 5F5F5F5FE50001 00"), + EOFValidationError::success); + + // Not enough inputs on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 010008 02000200050001 040000 00 0080000203800003 5F5FE50001 00"), + EOFValidationError::stack_underflow); +} + +TEST(eof_validation, jumpf_into_returning_stack_validation) +{ + // JUMPF into a function with the same number of outputs as current one + + // Exactly required inputs on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100060002 040000 00 008000000002000303020003 00 " + "5F5F5FE50002 50e4"), + EOFValidationError::success); + + // Extra items on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100070002 040000 00 008000000002000403020003 00 " + "5F5F5F5FE50002 50e4"), + EOFValidationError::non_empty_stack_on_terminating_instruction); + + // Not enough inputs on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100050002 040000 00 008000000002000203020003 00 " + "5F5FE50002 50e4"), + EOFValidationError::stack_underflow); + + // JUMPF into a function with fewer outputs than current one + // (0, 2) --JUMPF--> (3, 1): 3 inputs + 1 output = 4 items required + + // Exactly required inputs on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100070003 040000 00 008000000002000403010003 00 " + "5F5F5F5FE50002 5050e4"), + EOFValidationError::success); + + // Extra items on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100080003 040000 00 008000000002000503010003 00 " + "5F5F5F5F5FE50002 5050e4"), + EOFValidationError::non_empty_stack_on_terminating_instruction); + + // Not enough inputs on stack at JUMPF + EXPECT_EQ(validate_eof("EF0001 01000C 020003000100060003 040000 00 008000000002000303010003 00 " + "5F5F5FE50002 5050e4"), + EOFValidationError::stack_underflow); +} + +TEST(eof_validation, jumpf_stack_overflow) +{ + { + const auto code = eof1_bytecode(512 * push(1) + OP_JUMPF + bytecode{"0x0000"_hex}, 512); + EXPECT_EQ(validate_eof(code), EOFValidationError::success); + } + + { + const auto code = eof1_bytecode(513 * push(1) + OP_JUMPF + bytecode{"0x0000"_hex}, 513); + EXPECT_EQ(validate_eof(code), EOFValidationError::stack_overflow); + } + + { + const auto code = eof1_bytecode(1023 * push(1) + OP_JUMPF + bytecode{"0x0000"_hex}, 1023); + EXPECT_EQ(validate_eof(code), EOFValidationError::stack_overflow); + } +} + +TEST(eof_validation, jumpf_with_inputs_stack_overflow) +{ + { + const auto code = + bytecode{"ef0001 010008 020002 0402 0002 040000 00 008003FF 02800003"_hex} + + 1023 * OP_PUSH0 + OP_JUMPF + bytecode{"0x0001"_hex} + OP_PUSH0 + OP_STOP; + + EXPECT_EQ(validate_eof(code), EOFValidationError::success); + } + + { + const auto code = + bytecode{"ef0001 010008 020002 0402 0003 040000 00 008003FF 02800004"_hex} + + 1023 * OP_PUSH0 + OP_JUMPF + bytecode{"0x0001"_hex} + OP_PUSH0 + OP_PUSH0 + OP_STOP; + + EXPECT_EQ(validate_eof(code), EOFValidationError::stack_overflow); + } + + { + const auto code = + bytecode{"ef0001 010008 020002 0403 0002 040000 00 008003FF 02800003"_hex} + + 1024 * OP_PUSH0 + OP_JUMPF + bytecode{"0x0001"_hex} + OP_PUSH0 + OP_STOP; + + EXPECT_EQ(validate_eof(code), EOFValidationError::stack_overflow); + } +}