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

EIP-4750: EOF - Functions #497

Closed
wants to merge 74 commits into from
Closed
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
581ce39
test: Helper to check if current VM is Advanced
gumb0 Mar 10, 2022
4b1dad4
baseline: Implement EIP-663 DUPN SWAPN
rodiazet Nov 30, 2022
3e0ab0e
test: Add EIP-663 DUPN SWAPN unit tests
rodiazet Nov 28, 2022
b6d103b
Merge pull request #529 from ethereum/eip-663
rodiazet Dec 13, 2022
b14fad9
Set Opcode underlaying storage to uint8_t (#537)
chfast Dec 13, 2022
94b8a92
precompiles: Implement gas cost analysis
chfast Jun 17, 2022
c776b42
precompiles: Cache precompiles' execution results
chfast Jul 16, 2022
15fe385
precompiles: Dump and load precompiles' cache
chfast Aug 1, 2022
5cae37a
precompiles: Add JSON stub of precompiles
chfast Aug 1, 2022
0f43598
ci: Enable precompiles stub for state tests
chfast Aug 2, 2022
6b79a34
Merge pull request #524 from ethereum/state_precompiles_stub
chfast Dec 15, 2022
9d4697f
ci: Windows build via CircleCI (#539)
rodiazet Dec 16, 2022
5be5834
cmake: Upgrade dependencies (#540)
chfast Dec 16, 2022
342bc4c
statetest: Support EOF/Shanghai testing (hack)
chfast Oct 9, 2022
12de80b
tracing: Dump call input
chfast Nov 2, 2022
8c43313
eof: Validate initcode and already deployed code
chfast Nov 2, 2022
a0ea267
eof: Validate to-be-deployed EOF code
chfast Nov 2, 2022
233d5c4
Revert "tracing: Dump call input"
chfast Dec 4, 2022
95a69d5
Implement RJUMP and RJUMPI in Baseline
gumb0 Dec 6, 2022
cd22502
test: Tests for RJUMP/RJUMPI
gumb0 Dec 6, 2022
e592a80
Validation of RJUMP* instructions
gumb0 Apr 4, 2022
75b9dbe
test: Tests for RJUMP/RJUMPI instruction validation
gumb0 Dec 6, 2022
02f63d4
Undefine RJUMP* instructions in non-EOF code
gumb0 Dec 7, 2022
cba432c
Fix eof branch build after rebasing
rodiazet Dec 15, 2022
4e236de
EIP-3860: Limit and meter initcode
yperbasis Nov 30, 2022
7377eb8
Add "Merge+" rev name suppport
rodiazet Dec 15, 2022
7e11e92
Apply init code cost (EIP3860)
rodiazet Dec 15, 2022
fdba7dc
Limit init code size
rodiazet Dec 15, 2022
0898601
Fix a subtel bug for mining reward for pre EIP158
rodiazet Dec 15, 2022
4c80f2f
Fix the rest of state tests by distinguishing with applied EIPs
rodiazet Dec 16, 2022
2c3d305
Update state tests to the newest tests/develop
rodiazet Dec 16, 2022
c4a3775
Add CALLF/RETF instructions
gumb0 Dec 7, 2022
03ac34d
Implement EIP-4750 EOF validation
gumb0 Aug 23, 2022
18f36e4
test: Add EOF functions example test
gumb0 Dec 6, 2022
7619e30
Fix EOF validation with type section
chfast Sep 27, 2022
392bb44
Implement CALLF/RETF
gumb0 Dec 7, 2022
f072bf3
Pass all code sections as executable code
chfast Sep 28, 2022
0a46f69
Add unit test with big example
gumb0 Dec 6, 2022
eb6fec5
Fix typo
gumb0 Sep 29, 2022
1b18fca
Add more validation unit tests
gumb0 Sep 29, 2022
955038f
Fix building after rebasing
rodiazet Dec 19, 2022
166dbf0
Fix Windows build
rodiazet Dec 19, 2022
75a38b2
Bump stack usage
rodiazet Dec 19, 2022
e463a46
Implement EOF functions according to the newest unified spec
rodiazet Dec 19, 2022
3bdacd8
Update unit tests to reflect the unified spec.
rodiazet Dec 20, 2022
054f4bb
test: Disable all unit tests for Advanced
chfast Dec 21, 2022
9402833
Fix unit tests and add section order test
rodiazet Dec 21, 2022
2a4062b
Allow empty data section
chfast Dec 21, 2022
234b884
Migrate bytecode helpers to new EOF format
chfast Dec 21, 2022
8bc94db
Fix and update EOF validation unit tests
rodiazet Dec 21, 2022
5c222d3
Fix linter errors
rodiazet Dec 21, 2022
4c5f27a
Make types section mandatory
rodiazet Dec 21, 2022
d0a9c20
Remove terminating instruction requirement
rodiazet Dec 21, 2022
2a1219c
Update unit tests after removing terminating instruction requirement
rodiazet Dec 21, 2022
bdcc8d4
Implement RJUMPV
rodiazet Dec 22, 2022
f023c37
Fix sanitizers error
rodiazet Dec 23, 2022
b33a74e
Implement max stack height validation
rodiazet Dec 27, 2022
a5f2c4f
eof: Switch instruction validation to baseline cost table
chfast Dec 27, 2022
bcc15ac
eof: Reject deprecated instructions
chfast Dec 27, 2022
f4ea517
eof: Fix unit tests
rodiazet Dec 27, 2022
8c041ed
test: Add EOF data only contract test
chfast Dec 28, 2022
1c91f92
Fix sanitizers testing error
rodiazet Dec 28, 2022
4667b64
host: Enforce EOF code from EOF initcode
chfast Dec 28, 2022
79baead
eof: Ensure that eof contract creates only valid eof contract
rodiazet Dec 28, 2022
403e970
test: Add basic test for RJUMPV
gumb0 Dec 28, 2022
21c6466
Fix off-by-one error in RJUMPV implementation
gumb0 Dec 28, 2022
f6e6b43
eof: Add more RJUMPV tests
rodiazet Dec 29, 2022
4e0e7d4
eof: Fix 0 count RJUMPV test
rodiazet Dec 29, 2022
dcbc983
Fix linter errors
rodiazet Dec 29, 2022
b051628
eof: Add long jump test for RJUMPV
rodiazet Dec 29, 2022
7bd9567
eof: Limit number of possible inputs and outputs.
rodiazet Jan 2, 2023
5ca9116
eof: Add tests for max stack height
rodiazet Jan 2, 2023
0520f2e
eof: get_error_message()
chfast Jan 2, 2023
62bddb3
Add eofparse testing tool
chfast Jan 2, 2023
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 CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright 2019 The evmone Authors.
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.16...3.23)
cmake_minimum_required(VERSION 3.16...3.24)

if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/evmc/.git)
message(FATAL_ERROR "Git submodules not initialized, execute:\n git submodule update --init")
Expand Down
59 changes: 51 additions & 8 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
version: 2.1
orbs:
win: circleci/windows@5.0

executors:
lint:
Expand Down Expand Up @@ -76,6 +78,12 @@ commands:
command: |
curl -L https://github.com/Kitware/CMake/releases/download/v<<parameters.version>>/cmake-<<parameters.version>>-linux-x86_64.tar.gz | sudo tar -xz --strip=1

checkout_submodules:
steps:
- run:
name: "Update submodules"
command: git submodule update --init --recursive

build_silkworm:
parameters:
branch:
Expand Down Expand Up @@ -145,9 +153,7 @@ commands:
description: "Build"
steps:
- checkout
- run:
name: "Update submodules"
command: git submodule update --init --recursive
- checkout_submodules
- run:
name: "Environment"
command: |
Expand Down Expand Up @@ -195,6 +201,7 @@ commands:
steps:
- run:
name: "Test"
shell: bash
working_directory: ~/build
command: ctest -R ${TESTS_FILTER:-'.*'} --schedule-random --output-on-failure --parallel $CMAKE_BUILD_PARALLEL_LEVEL --output-junit ~/test_results/evmone.xml
- store_test_results:
Expand Down Expand Up @@ -241,8 +248,9 @@ commands:
steps:
- run:
name: "Build Package"
shell: bash
working_directory: ~/package
command: cmake --build ~/build --target package && mv ~/build/evmone*.tar.gz* .
command: cmake --build ~/build --target package && mv ~/build/evmone-*.* .
- store_artifacts:
path: ~/package
destination: package
Expand Down Expand Up @@ -286,6 +294,38 @@ jobs:
- test
- package

release-windows:
executor: win/server-2022
environment:
CMAKE_BUILD_TYPE: Release
CMAKE_BUILD_PARALLEL_LEVEL: 4
steps:
- checkout
- checkout_submodules
- run:
name: "Setup environment (bash)"
shell: bash
command: |
echo 'export PATH=$PATH:"/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin"' >> $BASH_ENV
- run:
name: 'Configure'
shell: powershell
command: |
$ErrorActionPreference = "Stop"
& 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch amd64
which cmake
cmake -S . -B ~/build -G Ninja -DCMAKE_INSTALL_PREFIX=C:\install -DEVMONE_TESTING=ON
- run:
name: 'Build'
shell: powershell
command: |
$ErrorActionPreference = "Stop"
& 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' -Arch amd64
cmake --build ~/build
- test
- package


release-macos:
executor: macos
environment:
Expand Down Expand Up @@ -350,12 +390,12 @@ jobs:
steps:
- build
- download_consensus_tests:
rev: v11.1
rev: develop
- run:
name: "State tests"
working_directory: ~/build
# TODO: Some state tests are expected to fail because precompiles are not implemented.
command: bin/evmone-statetest ~/tests/GeneralStateTests ~/tests/LegacyTests/Constantinople/GeneralStateTests || true
command: EVMONE_PRECOMPILES_STUB=~/project/test/state/precompiles_stub.json bin/evmone-statetest ~/tests/GeneralStateTests ~/tests/LegacyTests/Constantinople/GeneralStateTests
- collect_coverage_gcc
- upload_coverage:
flags: statetests
Expand Down Expand Up @@ -505,15 +545,18 @@ workflows:
filters:
tags:
only: /.*/
- release-windows:
filters:
tags:
only: /.*/
- release-macos:
filters:
branches:
ignore: /.*/
tags:
only: /.*/
- deploy:
requires:
- release-linux
- release-windows
- release-macos
filters:
branches:
Expand Down
4 changes: 2 additions & 2 deletions cmake/Hunter/init.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set(HUNTER_CONFIGURATION_TYPES Release CACHE STRING "Build type of Hunter packag
include(HunterGate)

HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.24.5.tar.gz"
SHA1 "d7279c19372938dbb14c6ed511bdcb6e938ac5df"
URL "https://github.com/cpp-pm/hunter/archive/v0.24.11.tar.gz"
SHA1 "e49fb20a135675e406e95fbe9a591a630ccbbeaf"
LOCAL
)
3 changes: 2 additions & 1 deletion lib/evmone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_library(evmone
instructions_traits.hpp
instructions_xmacro.hpp
opcodes_helpers.h
eips.hpp
tracing.cpp
tracing.hpp
vm.cpp
Expand All @@ -41,7 +42,7 @@ if(CABLE_COMPILER_GNULIKE)
target_compile_options(
evmone PRIVATE
-fno-exceptions
$<$<CXX_COMPILER_ID:GNU>:-Wstack-usage=2500>
$<$<CXX_COMPILER_ID:GNU>:-Wstack-usage=2600>
)
if(NOT SANITIZE MATCHES undefined)
# RTTI can be disabled except for UBSan which checks vptr integrity.
Expand Down
5 changes: 3 additions & 2 deletions lib/evmone/advanced_execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ evmc_result execute(evmc_vm* /*unused*/, const evmc_host_interface* host, evmc_h
{
if (rev >= EVMC_SHANGHAI)
{
const auto eof1_header = read_valid_eof1_header(container.begin());
analysis = analyze(rev, {&container[eof1_header.code_begin()], eof1_header.code_size});
const auto eof1_header = read_valid_eof1_header(container);
analysis =
analyze(rev, {&container[eof1_header.code_begin(0)], eof1_header.code_sizes[0]});
}
else
// Skip analysis, because it will recognize 01 section id as OP_ADD and return
Expand Down
12 changes: 11 additions & 1 deletion lib/evmone/advanced_instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0

#include "advanced_analysis.hpp"
#include "eips.hpp"
#include "instructions.hpp"
#include "instructions_traits.hpp"

Expand Down Expand Up @@ -216,7 +217,6 @@ const Instruction* op_undefined(const Instruction*, AdvancedExecutionState& stat
return state.exit(EVMC_UNDEFINED_INSTRUCTION);
}


constexpr std::array<instruction_exec_fn, 256> instruction_implementations = []() noexcept {
std::array<instruction_exec_fn, 256> table{};

Expand Down Expand Up @@ -245,12 +245,22 @@ constexpr std::array<instruction_exec_fn, 256> instruction_implementations = [](
table[OP_CREATE2] = op_create<OP_CREATE2>;
table[OP_STATICCALL] = op_call<OP_STATICCALL>;

table[OP_RJUMP] = op_undefined;
table[OP_RJUMPI] = op_undefined;
table[OP_RJUMPV] = op_undefined;
table[OP_CALLF] = op_undefined;
table[OP_RETF] = op_undefined;

table[OP_DUPN] = op_undefined;
table[OP_SWAPN] = op_undefined;

return table;
}();
} // namespace

EVMC_EXPORT const OpTable& get_op_table(evmc_revision rev) noexcept
{
rev = clear_eips(rev);
static constexpr auto op_tables = []() noexcept {
std::array<OpTable, EVMC_MAX_REVISION + 1> tables{};
for (size_t r = EVMC_FRONTIER; r <= EVMC_MAX_REVISION; ++r)
Expand Down
31 changes: 27 additions & 4 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,19 @@ CodeAnalysis analyze_legacy(bytes_view code)

CodeAnalysis analyze_eof1(bytes_view eof_container, const EOF1Header& header)
{
const auto executable_code = eof_container.substr(header.code_begin(), header.code_size);
return {executable_code, analyze_jumpdests(executable_code)};
auto beg = header.code_begin(0);
auto end = header.code_end(header.code_sizes.size() - 1);
const auto executable_code = eof_container.substr(beg, end - beg);

const auto o = header.code_offsets[0];
std::vector<uint16_t> offs;
for (auto x : header.code_offsets)
offs.push_back(x - o);

// FIXME: Better way of getting EOF version.
auto a = CodeAnalysis{executable_code, analyze_jumpdests(executable_code), eof_container[2]};
a.code_offsets = std::move(offs);
return a;
}
} // namespace

Expand All @@ -79,7 +90,7 @@ CodeAnalysis analyze(evmc_revision rev, bytes_view code)
if (rev < EVMC_SHANGHAI || !is_eof_code(code))
return analyze_legacy(code);

const auto eof1_header = read_valid_eof1_header(code.begin());
const auto eof1_header = read_valid_eof1_header(code);
return analyze_eof1(code, eof1_header);
}

Expand Down Expand Up @@ -321,7 +332,7 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana

const auto code = analysis.executable_code;

const auto& cost_table = get_baseline_cost_table(state.rev);
const auto& cost_table = get_baseline_cost_table(state.rev, analysis.eof_version);

auto* tracer = vm.get_tracer();
if (INTX_UNLIKELY(tracer != nullptr))
Expand Down Expand Up @@ -356,6 +367,18 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana
evmc_result execute(evmc_vm* c_vm, const evmc_host_interface* host, evmc_host_context* ctx,
evmc_revision rev, const evmc_message* msg, const uint8_t* code, size_t code_size) noexcept
{
if (rev >= EVMC_SHANGHAI && is_eof_code({code, code_size}))
{
// TODO(EOF): The initcode must be validated. Doing this just before execution is
// good because validation can be combined with analysis/loading. But consider also
// other places like create instructions.
if (validate_eof(rev, {code, code_size}) != EOFValidationError::success)
{
// TODO(EOF): This should never happen but protects against invalid tests for now.
return evmc::Result{EVMC_INTERNAL_ERROR}.release_raw();
}
}

auto vm = static_cast<VM*>(c_vm);
const auto jumpdest_map = analyze(rev, {code, code_size});
auto state =
Expand Down
6 changes: 4 additions & 2 deletions lib/evmone/baseline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class CodeAnalysis

bytes_view executable_code; ///< Executable code section.
JumpdestMap jumpdest_map; ///< Map of valid jump destinations.
uint8_t eof_version = 0; ///< The EOF version, 0 means legacy code.
std::vector<uint16_t> code_offsets;

private:
/// Padded code for faster legacy code execution.
Expand All @@ -38,8 +40,8 @@ class CodeAnalysis
m_padded_code{std::move(padded_code)}
{}

CodeAnalysis(bytes_view code, JumpdestMap map)
: executable_code{code}, jumpdest_map{std::move(map)}
CodeAnalysis(bytes_view code, JumpdestMap map, uint8_t eof_ver)
: executable_code{code}, jumpdest_map{std::move(map)}, eof_version{eof_ver}
{}
};
static_assert(std::is_move_constructible_v<CodeAnalysis>);
Expand Down
48 changes: 36 additions & 12 deletions lib/evmone/baseline_instruction_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,49 @@
// SPDX-License-Identifier: Apache-2.0

#include "baseline_instruction_table.hpp"
#include "eips.hpp"
#include "instructions_traits.hpp"

namespace evmone::baseline
{
const CostTable& get_baseline_cost_table(evmc_revision rev) noexcept
namespace
{
static constexpr auto cost_tables = []() noexcept {
std::array<CostTable, EVMC_MAX_REVISION + 1> tables{};
for (size_t r = EVMC_FRONTIER; r <= EVMC_MAX_REVISION; ++r)
constexpr auto common_cost_tables = []() noexcept {
std::array<CostTable, EVMC_MAX_REVISION + 1> tables{};
for (size_t r = EVMC_FRONTIER; r <= EVMC_MAX_REVISION; ++r)
{
auto& table = tables[r];
for (size_t i = 0; i < table.size(); ++i)
{
auto& table = tables[r];
for (size_t i = 0; i < table.size(); ++i)
{
table[i] = instr::gas_costs[r][i]; // Include instr::undefined in the table.
}
table[i] = instr::gas_costs[r][i]; // Include instr::undefined in the table.
}
return tables;
}();
}
return tables;
}();

return cost_tables[rev];
constexpr auto legacy_cost_tables = []() noexcept {
auto tables = common_cost_tables;
tables[EVMC_SHANGHAI][OP_RJUMP] = instr::undefined;
tables[EVMC_SHANGHAI][OP_RJUMPI] = instr::undefined;
return tables;
}();

constexpr auto eof_cost_tables = []() noexcept {
auto tables = common_cost_tables;
tables[EVMC_SHANGHAI][OP_JUMP] = instr::undefined;
tables[EVMC_SHANGHAI][OP_JUMPI] = instr::undefined;
tables[EVMC_SHANGHAI][OP_PC] = instr::undefined;
tables[EVMC_SHANGHAI][OP_CALLCODE] = instr::undefined;
tables[EVMC_SHANGHAI][OP_SELFDESTRUCT] = instr::undefined;
return tables;
}();

} // namespace

const CostTable& get_baseline_cost_table(evmc_revision rev, uint8_t eof_version) noexcept
{
rev = clear_eips(rev);
const auto& tables = (eof_version == 0) ? legacy_cost_tables : eof_cost_tables;
return tables[rev];
}
} // namespace evmone::baseline
4 changes: 3 additions & 1 deletion lib/evmone/baseline_instruction_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ namespace evmone::baseline
{
using CostTable = std::array<int16_t, 256>;

const CostTable& get_baseline_cost_table(evmc_revision rev) noexcept;
const CostTable& get_baseline_cost_table(evmc_revision rev, uint8_t eof_version) noexcept;

const CostTable& get_baseline_legacy_cost_table(evmc_revision rev) noexcept;
} // namespace evmone::baseline
Loading