Skip to content

Commit 46dc5ee

Browse files
authored
eof: Return constant hash of EXTCODEHASH of EOF (#1035)
Replace runtime evaluated `keccak256("EF00")` with a constant returned for an account with EOF code.
2 parents 2cd8bf7 + 02b6951 commit 46dc5ee

File tree

4 files changed

+28
-12
lines changed

4 files changed

+28
-12
lines changed

lib/evmone/eof.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <cassert>
1515
#include <limits>
1616
#include <numeric>
17-
#include <ostream>
1817
#include <queue>
1918
#include <unordered_set>
2019
#include <vector>
@@ -23,8 +22,6 @@ namespace evmone
2322
{
2423
namespace
2524
{
26-
constexpr uint8_t MAGIC_BYTES[] = {0xef, 0x00};
27-
constexpr bytes_view MAGIC{MAGIC_BYTES, std::size(MAGIC_BYTES)};
2825
constexpr uint8_t TERMINATOR = 0x00;
2926
constexpr uint8_t TYPE_SECTION = 0x01;
3027
constexpr uint8_t CODE_SECTION = 0x02;
@@ -50,7 +47,7 @@ size_t eof_header_size(const EOFSectionHeaders& headers) noexcept
5047
constexpr auto non_code_section_header_size = 3; // (SECTION_ID + SIZE) per each section
5148
constexpr auto section_size_size = 2;
5249

53-
auto header_size = std::size(MAGIC) + 1 + // 1 version byte
50+
auto header_size = std::size(EOF_MAGIC) + 1 + // 1 version byte
5451
non_code_section_count * non_code_section_header_size +
5552
sizeof(CODE_SECTION) + 2 + code_section_count * section_size_size +
5653
sizeof(TERMINATOR);
@@ -93,7 +90,7 @@ std::variant<EOFSectionHeaders, EOFValidationError> validate_section_headers(byt
9390
uint16_t section_num = 0;
9491
EOFSectionHeaders section_headers{};
9592
const auto container_end = container.end();
96-
auto it = container.begin() + std::size(MAGIC) + 1; // MAGIC + VERSION
93+
auto it = container.begin() + std::size(EOF_MAGIC) + 1; // MAGIC + VERSION
9794
uint8_t expected_section_id = TYPE_SECTION;
9895
while (it != container_end && state != State::terminated)
9996
{
@@ -719,7 +716,7 @@ size_t EOF1Header::data_size_position() const noexcept
719716
{
720717
const auto num_code_sections = code_sizes.size();
721718
const auto num_container_sections = container_sizes.size();
722-
return std::size(MAGIC) + 1 + // magic + version
719+
return std::size(EOF_MAGIC) + 1 + // magic + version
723720
3 + // type section kind + size
724721
3 + 2 * num_code_sections + // code sections kind + count + sizes
725722
// container sections kind + count + sizes
@@ -729,7 +726,7 @@ size_t EOF1Header::data_size_position() const noexcept
729726

730727
bool is_eof_container(bytes_view container) noexcept
731728
{
732-
return container.starts_with(MAGIC);
729+
return container.starts_with(EOF_MAGIC);
733730
}
734731

735732
std::variant<EOF1Header, EOFValidationError> validate_header(
@@ -806,7 +803,7 @@ std::variant<EOF1Header, EOFValidationError> validate_header(
806803
EOF1Header read_valid_eof1_header(bytes_view container)
807804
{
808805
EOFSectionHeaders section_headers;
809-
auto it = container.begin() + std::size(MAGIC) + 1; // MAGIC + VERSION
806+
auto it = container.begin() + std::size(EOF_MAGIC) + 1; // MAGIC + VERSION
810807
while (*it != TERMINATOR)
811808
{
812809
const auto section_id = *it++;

lib/evmone/eof.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,28 @@
44
#pragma once
55

66
#include <evmc/bytes.hpp>
7-
#include <evmc/evmc.h>
7+
#include <evmc/evmc.hpp>
88
#include <evmc/utils.h>
99
#include <cassert>
1010
#include <cstddef>
1111
#include <cstdint>
12-
#include <string>
12+
#include <string_view>
1313
#include <variant>
1414
#include <vector>
1515

1616
namespace evmone
1717
{
1818
using evmc::bytes;
1919
using evmc::bytes_view;
20+
using namespace evmc::literals;
21+
22+
constexpr uint8_t EOF_MAGIC_BYTES[] = {0xef, 0x00};
23+
constexpr bytes_view EOF_MAGIC{EOF_MAGIC_BYTES, std::size(EOF_MAGIC_BYTES)};
24+
25+
/// The value returned by EXTCODEHASH of an address with EOF code.
26+
/// See EIP-3540: https://eips.ethereum.org/EIPS/eip-3540#changes-to-execution-semantics.
27+
static constexpr auto EOF_CODE_HASH_SENTINEL =
28+
0x9dbf3648db8210552e9c4f75c6a1c3057c0ca432043bd648be15fe7be05646f5_bytes32;
2029

2130
struct EOFCodeType
2231
{

test/state/host.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,13 @@ size_t Host::get_code_size(const address& addr) const noexcept
113113

114114
bytes32 Host::get_code_hash(const address& addr) const noexcept
115115
{
116-
// TODO: Cache code hash. It will be needed also to compute the MPT hash.
117116
const auto* const acc = m_state.find(addr);
118-
return (acc != nullptr && !acc->is_empty()) ? keccak256(extcode(acc->code)) : bytes32{};
117+
if (acc == nullptr || acc->is_empty())
118+
return {};
119+
if (is_eof_container(acc->code))
120+
return EOF_CODE_HASH_SENTINEL;
121+
// TODO: Cache code hash. It will be needed also to compute the MPT hash.
122+
return keccak256(acc->code);
119123
}
120124

121125
size_t Host::copy_code(const address& addr, size_t code_offset, uint8_t* buffer_data,

test/unittests/eof_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <evmone/eof.hpp>
66
#include <gtest/gtest.h>
7+
#include <test/state/hash_utils.hpp>
78
#include <test/utils/bytecode.hpp>
89
#include <test/utils/utils.hpp>
910

@@ -115,3 +116,8 @@ TEST(eof, get_error_message)
115116
// NOLINTNEXTLINE(*.EnumCastOutOfRange)
116117
EXPECT_EQ(evmone::get_error_message(static_cast<EOFValidationError>(-1)), "<unknown>");
117118
}
119+
120+
TEST(eof, extcodehash_sentinel)
121+
{
122+
EXPECT_EQ(keccak256(EOF_MAGIC), EOF_CODE_HASH_SENTINEL);
123+
}

0 commit comments

Comments
 (0)