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

eof: Return constant hash of EXTCODEHASH of EOF #1035

Merged
merged 2 commits into from
Sep 30, 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
13 changes: 5 additions & 8 deletions lib/evmone/eof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <cassert>
#include <limits>
#include <numeric>
#include <ostream>
#include <queue>
#include <unordered_set>
#include <vector>
Expand All @@ -23,8 +22,6 @@ namespace evmone
{
namespace
{
constexpr uint8_t MAGIC_BYTES[] = {0xef, 0x00};
constexpr bytes_view MAGIC{MAGIC_BYTES, std::size(MAGIC_BYTES)};
constexpr uint8_t TERMINATOR = 0x00;
constexpr uint8_t TYPE_SECTION = 0x01;
constexpr uint8_t CODE_SECTION = 0x02;
Expand All @@ -50,7 +47,7 @@ size_t eof_header_size(const EOFSectionHeaders& headers) noexcept
constexpr auto non_code_section_header_size = 3; // (SECTION_ID + SIZE) per each section
constexpr auto section_size_size = 2;

auto header_size = std::size(MAGIC) + 1 + // 1 version byte
auto header_size = std::size(EOF_MAGIC) + 1 + // 1 version byte
non_code_section_count * non_code_section_header_size +
sizeof(CODE_SECTION) + 2 + code_section_count * section_size_size +
sizeof(TERMINATOR);
Expand Down Expand Up @@ -93,7 +90,7 @@ std::variant<EOFSectionHeaders, EOFValidationError> validate_section_headers(byt
uint16_t section_num = 0;
EOFSectionHeaders section_headers{};
const auto container_end = container.end();
auto it = container.begin() + std::size(MAGIC) + 1; // MAGIC + VERSION
auto it = container.begin() + std::size(EOF_MAGIC) + 1; // MAGIC + VERSION
uint8_t expected_section_id = TYPE_SECTION;
while (it != container_end && state != State::terminated)
{
Expand Down Expand Up @@ -719,7 +716,7 @@ size_t EOF1Header::data_size_position() const noexcept
{
const auto num_code_sections = code_sizes.size();
const auto num_container_sections = container_sizes.size();
return std::size(MAGIC) + 1 + // magic + version
return std::size(EOF_MAGIC) + 1 + // magic + version
3 + // type section kind + size
3 + 2 * num_code_sections + // code sections kind + count + sizes
// container sections kind + count + sizes
Expand All @@ -729,7 +726,7 @@ size_t EOF1Header::data_size_position() const noexcept

bool is_eof_container(bytes_view container) noexcept
{
return container.starts_with(MAGIC);
return container.starts_with(EOF_MAGIC);
}

std::variant<EOF1Header, EOFValidationError> validate_header(
Expand Down Expand Up @@ -806,7 +803,7 @@ std::variant<EOF1Header, EOFValidationError> validate_header(
EOF1Header read_valid_eof1_header(bytes_view container)
{
EOFSectionHeaders section_headers;
auto it = container.begin() + std::size(MAGIC) + 1; // MAGIC + VERSION
auto it = container.begin() + std::size(EOF_MAGIC) + 1; // MAGIC + VERSION
while (*it != TERMINATOR)
{
const auto section_id = *it++;
Expand Down
13 changes: 11 additions & 2 deletions lib/evmone/eof.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,28 @@
#pragma once

#include <evmc/bytes.hpp>
#include <evmc/evmc.h>
#include <evmc/evmc.hpp>
#include <evmc/utils.h>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

namespace evmone
{
using evmc::bytes;
using evmc::bytes_view;
using namespace evmc::literals;

constexpr uint8_t EOF_MAGIC_BYTES[] = {0xef, 0x00};
constexpr bytes_view EOF_MAGIC{EOF_MAGIC_BYTES, std::size(EOF_MAGIC_BYTES)};

/// The value returned by EXTCODEHASH of an address with EOF code.
/// See EIP-3540: https://eips.ethereum.org/EIPS/eip-3540#changes-to-execution-semantics.
static constexpr auto EOF_CODE_HASH_SENTINEL =
0x9dbf3648db8210552e9c4f75c6a1c3057c0ca432043bd648be15fe7be05646f5_bytes32;

struct EOFCodeType
{
Expand Down
8 changes: 6 additions & 2 deletions test/state/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ size_t Host::get_code_size(const address& addr) const noexcept

bytes32 Host::get_code_hash(const address& addr) const noexcept
{
// TODO: Cache code hash. It will be needed also to compute the MPT hash.
const auto* const acc = m_state.find(addr);
return (acc != nullptr && !acc->is_empty()) ? keccak256(extcode(acc->code)) : bytes32{};
if (acc == nullptr || acc->is_empty())
return {};
if (is_eof_container(acc->code))
return EOF_CODE_HASH_SENTINEL;
// TODO: Cache code hash. It will be needed also to compute the MPT hash.
return keccak256(acc->code);
}

size_t Host::copy_code(const address& addr, size_t code_offset, uint8_t* buffer_data,
Expand Down
6 changes: 6 additions & 0 deletions test/unittests/eof_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <evmone/eof.hpp>
#include <gtest/gtest.h>
#include <test/state/hash_utils.hpp>
#include <test/utils/bytecode.hpp>
#include <test/utils/utils.hpp>

Expand Down Expand Up @@ -115,3 +116,8 @@ TEST(eof, get_error_message)
// NOLINTNEXTLINE(*.EnumCastOutOfRange)
EXPECT_EQ(evmone::get_error_message(static_cast<EOFValidationError>(-1)), "<unknown>");
}

TEST(eof, extcodehash_sentinel)
{
EXPECT_EQ(keccak256(EOF_MAGIC), EOF_CODE_HASH_SENTINEL);
}