Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move EOF to Osaka #1060

Merged
merged 5 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ docker run --entrypoint evmone-bench ethereum/evmone /src/test/benchmarks
evmone supports EOFv1. Since EOF validation is done once during deploy-time, evmone does not revalidate during execution of bytecode. To force EOF revalidation, you can use the `validate_eof` option, example:

```
evmc run --vm libevmone.so,validate_eof --rev 13 "EF00"
evmc run --vm libevmone.so,validate_eof --rev 14 "EF00"
```

## References
Expand Down
18 changes: 7 additions & 11 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -391,18 +391,18 @@ jobs:
steps:
- build
- download_execution_spec_tests:
release: eip7692@v1.1.1
fixtures_suffix: eip7692
release: eip7692@v2.0.0
fixtures_suffix: eip7692-osaka
- run:
name: "EOF pre-release execution spec tests (state_tests)"
working_directory: ~/build
command: >
bin/evmone-statetest ~/spec-tests/fixtures/state_tests
bin/evmone-statetest ~/spec-tests/fixtures/state_tests/osaka
- run:
name: "EOF pre-release execution spec tests (blockchain_tests)"
working_directory: ~/build
command: >
bin/evmone-blockchaintest ~/spec-tests/fixtures/blockchain_tests
bin/evmone-blockchaintest ~/spec-tests/fixtures/blockchain_tests/osaka
- run:
name: "EOF pre-release execution spec tests (eof_tests)"
working_directory: ~/build
Expand All @@ -419,7 +419,8 @@ jobs:
steps:
- build
- download_execution_tests:
rev: v14.1
repo: "ipsilon/tests"
rev: "eof-osaka-20241028"
- run:
name: "State tests"
working_directory: ~/build
Expand All @@ -428,11 +429,6 @@ jobs:
~/tests/GeneralStateTests
~/tests/LegacyTests/Cancun/GeneralStateTests
~/tests/LegacyTests/Constantinople/GeneralStateTests
- run:
name: "EOF State tests"
working_directory: ~/build
command: |
bin/evmone-statetest ~/tests/EIPTests/StateTests/stEOF
- run:
name: "EOF validation tests"
working_directory: ~/build
Expand All @@ -458,7 +454,7 @@ jobs:
working_directory: ~/build
command: >
bin/evmone-blockchaintest
--gtest_filter='-*StateTests/stEOF/*.*:*StateTests/stEIP2537.*'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is nothing left here. We should remove this step. https://github.com/ethereum/tests/tree/develop/EIPTests/StateTests

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, and third: BTW, why do we exclude 2537? they pass

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2537 is covered by EEST. I would also ignore "examples". We are migrating away from ethereum/tests so let's limit the exposure. But I can do this in a separate PR with proper comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, separate PR seems cleaner

--gtest_filter='*:-*StateTests/stEIP2537.*'
~/tests/EIPTests/BlockchainTests/
- collect_coverage_gcc
- upload_coverage:
Expand Down
2 changes: 1 addition & 1 deletion evmc
Submodule evmc updated 2 files
+3 −3 README.md
+1 −1 include/evmc/evmc.h
2 changes: 1 addition & 1 deletion lib/evmone/advanced_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ evmc_result execute(evmc_vm* /*unused*/, const evmc_host_interface* host, evmc_h
const bytes_view container = {code, code_size};
if (is_eof_container(container))
{
if (rev >= EVMC_PRAGUE)
if (rev >= EVMC_OSAKA)
{
const auto eof1_header = read_valid_eof1_header(container);
analysis = analyze(rev, eof1_header.get_code(container, 0));
Expand Down
2 changes: 1 addition & 1 deletion lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ std::variant<EOF1Header, EOFValidationError> validate_header(
if (version != 1)
return EOFValidationError::eof_version_unknown;

if (rev < EVMC_PRAGUE)
if (rev < EVMC_OSAKA)
return EOFValidationError::eof_version_unknown;

// `offset` variable handled below is known to not be greater than the container size, as
Expand Down
2 changes: 1 addition & 1 deletion lib/evmone/instructions_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ Result create_impl(StackTop stack, int64_t gas_left, ExecutionState& state) noex
msg.input_data = &state.memory[init_code_offset];
msg.input_size = init_code_size;

if (state.rev >= EVMC_PRAGUE)
if (state.rev >= EVMC_OSAKA)
{
// EOF initcode is not allowed for legacy creation
if (is_eof_container({msg.input_data, msg.input_size}))
Expand Down
40 changes: 20 additions & 20 deletions lib/evmone/instructions_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,35 +171,35 @@ constexpr inline GasCostTable gas_costs = []() noexcept {
table[EVMC_CANCUN][OP_MCOPY] = 3;

table[EVMC_PRAGUE] = table[EVMC_CANCUN];
table[EVMC_PRAGUE][OP_DUPN] = 3;
table[EVMC_PRAGUE][OP_SWAPN] = 3;
table[EVMC_PRAGUE][OP_EXCHANGE] = 3;
table[EVMC_PRAGUE][OP_RJUMP] = 2;
table[EVMC_PRAGUE][OP_RJUMPI] = 4;
table[EVMC_PRAGUE][OP_RJUMPV] = 4;
table[EVMC_PRAGUE][OP_CALLF] = 5;
table[EVMC_PRAGUE][OP_RETF] = 3;
table[EVMC_PRAGUE][OP_JUMPF] = 5;
table[EVMC_PRAGUE][OP_DATALOAD] = 4;
table[EVMC_PRAGUE][OP_DATALOADN] = 3;
table[EVMC_PRAGUE][OP_DATASIZE] = 2;
table[EVMC_PRAGUE][OP_DATACOPY] = 3;
table[EVMC_PRAGUE][OP_RETURNDATALOAD] = 3;
table[EVMC_PRAGUE][OP_EXTCALL] = warm_storage_read_cost;
table[EVMC_PRAGUE][OP_EXTDELEGATECALL] = warm_storage_read_cost;
table[EVMC_PRAGUE][OP_EXTSTATICCALL] = warm_storage_read_cost;
table[EVMC_PRAGUE][OP_EOFCREATE] = 32000;
table[EVMC_PRAGUE][OP_RETURNCONTRACT] = 0;

table[EVMC_OSAKA] = table[EVMC_PRAGUE];
table[EVMC_OSAKA][OP_DUPN] = 3;
table[EVMC_OSAKA][OP_SWAPN] = 3;
table[EVMC_OSAKA][OP_EXCHANGE] = 3;
table[EVMC_OSAKA][OP_RJUMP] = 2;
table[EVMC_OSAKA][OP_RJUMPI] = 4;
table[EVMC_OSAKA][OP_RJUMPV] = 4;
table[EVMC_OSAKA][OP_CALLF] = 5;
table[EVMC_OSAKA][OP_RETF] = 3;
table[EVMC_OSAKA][OP_JUMPF] = 5;
table[EVMC_OSAKA][OP_DATALOAD] = 4;
table[EVMC_OSAKA][OP_DATALOADN] = 3;
table[EVMC_OSAKA][OP_DATASIZE] = 2;
table[EVMC_OSAKA][OP_DATACOPY] = 3;
table[EVMC_OSAKA][OP_RETURNDATALOAD] = 3;
table[EVMC_OSAKA][OP_EXTCALL] = warm_storage_read_cost;
table[EVMC_OSAKA][OP_EXTDELEGATECALL] = warm_storage_read_cost;
table[EVMC_OSAKA][OP_EXTSTATICCALL] = warm_storage_read_cost;
table[EVMC_OSAKA][OP_EOFCREATE] = 32000;
table[EVMC_OSAKA][OP_RETURNCONTRACT] = 0;

return table;
}();

static_assert(gas_costs[EVMC_MAX_REVISION][OP_ADD] > 0, "gas costs missing for a revision");

/// The revision related to introduction of the EOFv1.
constexpr auto REV_EOF1 = EVMC_PRAGUE;
constexpr auto REV_EOF1 = EVMC_OSAKA;


/// The EVM instruction traits.
Expand Down
2 changes: 1 addition & 1 deletion test/eofparse/eofparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int main(int argc, char* argv[])
}

const auto& eof = *o;
const auto err = evmone::validate_eof(EVMC_PRAGUE, container_kind, eof);
const auto err = evmone::validate_eof(EVMC_OSAKA, container_kind, eof);
if (err != evmone::EOFValidationError::success)
{
std::cout << "err: " << evmone::get_error_message(err) << "\n";
Expand Down
2 changes: 1 addition & 1 deletion test/eofparsefuzz/eofparsefuzz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size) noexcept
{
const evmone::bytes_view eof{data, data_size};
if (evmone::validate_eof(EVMC_PRAGUE, evmone::ContainerKind::runtime, eof) ==
if (evmone::validate_eof(EVMC_OSAKA, evmone::ContainerKind::runtime, eof) ==
evmone::EOFValidationError::success)
(void)evmone::read_valid_eof1_header(eof);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion test/eoftest/eoftest_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct EOFValidationTest
{
struct Expectation
{
evmc_revision rev = EVMC_PRAGUE;
evmc_revision rev = EVMC_OSAKA;
bool result = false;
};
std::string name;
Expand Down
8 changes: 4 additions & 4 deletions test/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,22 @@ DUP1,4
{\"pc\":6,\"op\":3,\"gas\":\"0xf4234\",\"gasCost\":\"0x3\",\"memSize\":0,\"stack\":\\[\"0x0\",\"0x4\"\\],\"depth\":1,\"refund\":0,\"opName\":\"SUB\"}
")

add_test(NAME ${PREFIX}/validate_eof COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 13 EF0001)
add_test(NAME ${PREFIX}/validate_eof COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 14 EF0001)
set_tests_properties(
${PREFIX}/validate_eof PROPERTIES PASS_REGULAR_EXPRESSION
"contract validation failure")

add_test(NAME ${PREFIX}/validate_eof_success COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 13 EF00010100040200010001040000000080000000)
add_test(NAME ${PREFIX}/validate_eof_success COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 14 EF00010100040200010001040000000080000000)
set_tests_properties(
${PREFIX}/validate_eof_success PROPERTIES PASS_REGULAR_EXPRESSION
"Result: success")

add_test(NAME ${PREFIX}/validate_eof_create COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 13 --create EF00010100040200010001040000000080000000)
add_test(NAME ${PREFIX}/validate_eof_create COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 14 --create EF00010100040200010001040000000080000000)
set_tests_properties(
${PREFIX}/validate_eof_create PROPERTIES PASS_REGULAR_EXPRESSION
"contract validation failure")

add_test(NAME ${PREFIX}/validate_eof_create_success COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 13 --create EF00010100040200010004030001001404000000008000025F5FEE00EF00010100040200010001040000000080000000)
add_test(NAME ${PREFIX}/validate_eof_create_success COMMAND evmc::tool --vm $<TARGET_FILE:evmone>,validate_eof run --rev 14 --create EF00010100040200010004030001001404000000008000025F5FEE00EF00010100040200010001040000000080000000)
set_tests_properties(
${PREFIX}/validate_eof_create_success PROPERTIES PASS_REGULAR_EXPRESSION
"Result: success")
Expand Down
2 changes: 1 addition & 1 deletion test/integration/statetest/eof/invalid_eof_in_state.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"currentTimestamp": "0x03e8"
},
"post": {
"Prague": [
"Osaka": [
{
"hash": "0xe8010ce590f401c9d61fef8ab05bea9bcec24281b795e5868809bc4e515aa530",
"indexes": {
Expand Down
2 changes: 1 addition & 1 deletion test/state/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ evmc::Result Host::create(const evmc_message& msg) noexcept

if (!code.empty() && code[0] == 0xEF)
{
if (m_rev >= EVMC_PRAGUE)
if (m_rev >= EVMC_OSAKA)
{
// Only EOFCREATE/EOF-creation-tx is allowed to deploy code starting with EF.
// It must be valid EOF, which was validated before execution.
Expand Down
2 changes: 1 addition & 1 deletion test/state/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ evmc_message build_message(
const auto recipient = tx.to.has_value() ? *tx.to : evmc::address{};

const auto is_legacy_eof_create =
rev >= EVMC_PRAGUE && !tx.to.has_value() && is_eof_container(tx.data);
rev >= EVMC_OSAKA && !tx.to.has_value() && is_eof_container(tx.data);

return {.kind = is_legacy_eof_create ? EVMC_EOFCREATE :
tx.to.has_value() ? EVMC_CALL :
Expand Down
2 changes: 1 addition & 1 deletion test/statetest/statetest_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ void validate_state(const TestState& state, evmc_revision rev)
// https://github.com/ethereum/tests/issues/1331
if (is_eof_container(acc.code))
{
if (rev >= EVMC_PRAGUE)
if (rev >= EVMC_OSAKA)
{
if (const auto result = validate_eof(rev, ContainerKind::runtime, acc.code);
result != EOFValidationError::success)
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/analysis_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ TEST(analysis, example1_eof1)
eof_bytecode(push(0x2a) + push(0x1e) + OP_MSTORE8 + OP_MSIZE + push(0) + OP_SSTORE, 2)
.data("deadbeef");
const auto header = evmone::read_valid_eof1_header(code);
const auto analysis = analyze(EVMC_PRAGUE, header.get_code(code, 0));
const auto analysis = analyze(EVMC_OSAKA, header.get_code(code, 0));

ASSERT_EQ(analysis.instrs.size(), 8);

Expand Down
12 changes: 6 additions & 6 deletions test/unittests/eof_example_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ TEST_F(state_transition, eof_examples_minimal)
//
// A minimal valid EOF container doing nothing.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

const auto eof_code = bytecode(
// Code section: STOP
Expand Down Expand Up @@ -50,7 +50,7 @@ TEST_F(state_transition, eof_examples_static_relative_jump_loop)
//
// EOF container looping infinitely using the static relative jump instruction RJUMP.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

const auto eof_code = bytecode(
// Code section: RJUMP back to start (-3)
Expand Down Expand Up @@ -87,7 +87,7 @@ TEST_F(state_transition, eof_examples_callf)
// EOF container with two code sections, one calling the other passing a single argument on the
// stack and retrieving the same single value back from the stack on return.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

const auto eof_code = bytecode(
// First code section: PUSH1(0x2A),
Expand Down Expand Up @@ -125,7 +125,7 @@ TEST_F(state_transition, eof_examples_creation_tx)
//
// A creation transaction used to create a new EOF contract.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

const auto initcontainer = bytecode(
//////////////////
Expand Down Expand Up @@ -166,7 +166,7 @@ TEST_F(state_transition, eof_examples_eofcreate)
// A factory contract with an EOFCREATE instruction is being called in order
// to deploy its subcontainer as a new EOF contract.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

const auto factory = bytecode(
//////////////////
Expand Down Expand Up @@ -228,7 +228,7 @@ TEST_F(state_transition, eof_examples_data)
//
// A basic EOF contract with a data section being used to load a byte of data onto the stack.

rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;

// clang-format off
const auto eof_code = bytecode(
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/eof_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ TEST(eof, read_valid_eof1_header)
{
const auto code = from_spaced_hex(test_case.code).value();
EXPECT_EQ(
validate_eof(EVMC_PRAGUE, ContainerKind::runtime, code), EOFValidationError::success)
validate_eof(EVMC_OSAKA, ContainerKind::runtime, code), EOFValidationError::success)
<< test_case.code;

const auto header = read_valid_eof1_header(code);
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/eof_validation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class eof_validation : public ExportableFixture
std::string name;
};

evmc_revision rev = EVMC_PRAGUE;
evmc_revision rev = EVMC_OSAKA;
std::vector<TestCase> test_cases;

/// Adds the case to test cases.
Expand Down
4 changes: 2 additions & 2 deletions test/unittests/eof_validation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ TEST_F(eof_validation, EOF1_too_many_code_sections)

TEST_F(eof_validation, EOF1_undefined_opcodes)
{
const auto& gas_table = evmone::instr::gas_costs[EVMC_PRAGUE];
const auto& gas_table = evmone::instr::gas_costs[EVMC_OSAKA];

for (uint16_t opcode = 0; opcode <= 0xff; ++opcode)
{
Expand All @@ -309,7 +309,7 @@ TEST_F(eof_validation, EOF1_undefined_opcodes)
opcode == OP_DATALOADN || opcode == OP_JUMPF || opcode == OP_EOFCREATE ||
opcode == OP_RETURNCONTRACT)
continue;
// These opcodes are deprecated since Prague.
// These opcodes are deprecated since Osaka.
// gas_cost table current implementation does not allow to undef instructions.
if (opcode == OP_JUMP || opcode == OP_JUMPI || opcode == OP_PC || opcode == OP_CALLCODE ||
opcode == OP_SELFDESTRUCT || opcode == OP_CALL || opcode == OP_STATICCALL ||
Expand Down
8 changes: 4 additions & 4 deletions test/unittests/evm_calls_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,28 +764,28 @@ TEST_P(evm, returndatacopy_outofrange_highbits)

TEST_P(evm, returndataload_undefined_in_legacy)
{
rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;
execute(staticcall(0) + returndataload(0));
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);
}

TEST_P(evm, extcall_undefined_in_legacy)
{
rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;
execute(extcall(0));
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);
}

TEST_P(evm, extdelegatecall_undefined_in_legacy)
{
rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;
execute(extdelegatecall(0));
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);
}

TEST_P(evm, extstaticcall_undefined_in_legacy)
{
rev = EVMC_PRAGUE;
rev = EVMC_OSAKA;
execute(extstaticcall(0));
EXPECT_STATUS(EVMC_UNDEFINED_INSTRUCTION);
}
Expand Down
Loading