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

Wasm compilation of core_test #129

Merged
merged 5 commits into from
Jan 5, 2021
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
6 changes: 4 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2020 The Silkworm Authors
# Copyright 2020-2021 The Silkworm Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,7 +37,7 @@ commands:
- run:
name: "Cmake"
working_directory: ~/build
command: cmake ../project -DCMAKE_BUILD_TYPE=$BUILD_TYPE
command: cmake ../project -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSILKWORM_CLANG_COVERAGE=$CLANG_COVERAGE
- save_cache:
name: "Save Hunter cache"
key: *hunter-cache-key
Expand Down Expand Up @@ -66,6 +66,7 @@ jobs:
linux-gcc-7:
environment:
BUILD_TYPE: Debug
CLANG_COVERAGE: OFF
docker:
- image: ethereum/cpp-build-env:12-gcc-7
steps:
Expand All @@ -76,6 +77,7 @@ jobs:
linux-clang-coverage:
environment:
BUILD_TYPE: Debug
CLANG_COVERAGE: ON
docker:
- image: ethereum/cpp-build-env:14-clang-10
steps:
Expand Down
36 changes: 22 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[[
Copyright 2020 The Silkworm Authors
Copyright 2020-2021 The Silkworm Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -65,16 +65,16 @@ if(NOT SILKWORM_CORE_ONLY)
include(cmake/Hunter/extra_packages.cmake)
endif()

# Profing and coverage options
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang$")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
# coverage
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
add_link_options(-fprofile-instr-generate -fcoverage-mapping)
else()
# profiling
add_compile_options(-gline-tables-only)
endif()
option(SILKWORM_CLANG_COVERAGE "Clang instrumentation for code coverage reports" OFF)

if(SILKWORM_CLANG_COVERAGE)
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
add_link_options(-fprofile-instr-generate -fcoverage-mapping)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang$" AND CMAKE_BUILD_TYPE STREQUAL "Release")
# useful for performance profiling
add_compile_options(-gline-tables-only)
endif()

# GMP
Expand Down Expand Up @@ -183,12 +183,20 @@ add_library(evmone evmone/lib/evmone/analysis.cpp
target_include_directories(evmone PUBLIC evmone/lib/evmone)
target_link_libraries(evmone PUBLIC evmc intx::intx PRIVATE keccak)

if(MSVC)
target_compile_options(evmone PRIVATE /EHsc)
else()
target_compile_options(evmone PRIVATE -fno-exceptions)
endif()

# Silkworm itself
add_subdirectory(core)

if(NOT SILKWORM_CORE_ONLY)
add_subdirectory(db)
add_subdirectory(tg_api)
if(NOT SILKWORM_HAS_PARENT)
add_subdirectory(cmd)
endif()
endif()

if(NOT SILKWORM_HAS_PARENT)
add_subdirectory(cmd)
endif()
58 changes: 31 additions & 27 deletions cmd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[[
Copyright 2020 The Silkworm Authors
Copyright 2020-2021 The Silkworm Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,38 +32,42 @@ else()
target_compile_options(core_test PRIVATE -fno-exceptions)
endif()

find_package(absl CONFIG REQUIRED)
find_package(Boost CONFIG REQUIRED COMPONENTS filesystem)
if(NOT SILKWORM_CORE_ONLY)

file(GLOB_RECURSE SILKWORM_DB_TESTS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/db/silkworm/*_test.cpp")
add_executable(db_test unit_test.cpp ${SILKWORM_DB_TESTS})
target_link_libraries(db_test silkworm_db Catch2::Catch2)
find_package(absl CONFIG REQUIRED)
find_package(Boost CONFIG REQUIRED COMPONENTS filesystem)

add_executable(check_changes check_changes.cpp)
target_link_libraries(check_changes PRIVATE silkworm_db absl::flags_parse absl::time Boost::filesystem)
file(GLOB_RECURSE SILKWORM_DB_TESTS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/db/silkworm/*_test.cpp")
add_executable(db_test unit_test.cpp ${SILKWORM_DB_TESTS})
target_link_libraries(db_test silkworm_db Catch2::Catch2)

add_executable(scan_txs scan_txs.cpp)
target_link_libraries(scan_txs PRIVATE silkworm_db absl::flags_parse absl::time Boost::filesystem)
add_executable(check_changes check_changes.cpp)
target_link_libraries(check_changes PRIVATE silkworm_db absl::flags_parse absl::time Boost::filesystem)

find_package(CLI11 CONFIG REQUIRED)
add_executable(scan_txs scan_txs.cpp)
target_link_libraries(scan_txs PRIVATE silkworm_db absl::flags_parse absl::time Boost::filesystem)

add_executable(check_senders check_senders.cpp)
target_link_libraries(check_senders PRIVATE silkworm_db CLI11::CLI11 Boost::filesystem)
find_package(CLI11 CONFIG REQUIRED)

add_executable(dbtool dbtool.cpp)
target_link_libraries(dbtool PRIVATE silkworm_db CLI11::CLI11 Boost::filesystem)
add_executable(check_senders check_senders.cpp)
target_link_libraries(check_senders PRIVATE silkworm_db CLI11::CLI11 Boost::filesystem)

add_executable(execute execute.cpp)
target_link_libraries(execute PRIVATE silkworm_db silkworm_tg_api CLI11::CLI11 Boost::filesystem)
target_include_directories(execute PRIVATE ${CMAKE_SOURCE_DIR})
add_executable(dbtool dbtool.cpp)
target_link_libraries(dbtool PRIVATE silkworm_db CLI11::CLI11 Boost::filesystem)

# Ethereum Consensus Tests
find_package(nlohmann_json CONFIG REQUIRED)
add_executable(consensus consensus.cpp)
target_compile_definitions(consensus PRIVATE SILKWORM_CONSENSUS_TEST_DIR="${CMAKE_SOURCE_DIR}/tests")
target_link_libraries(consensus PRIVATE silkworm_core nlohmann_json::nlohmann_json Boost::filesystem)
add_executable(execute execute.cpp)
target_link_libraries(execute PRIVATE silkworm_db silkworm_tg_api CLI11::CLI11 Boost::filesystem)
target_include_directories(execute PRIVATE ${CMAKE_SOURCE_DIR})

# Benchmarks
find_package(benchmark CONFIG REQUIRED)
add_executable(benchmark_precompile benchmark_precompile.cpp)
target_link_libraries(benchmark_precompile silkworm_core benchmark::benchmark)
# Ethereum Consensus Tests
find_package(nlohmann_json CONFIG REQUIRED)
add_executable(consensus consensus.cpp)
target_compile_definitions(consensus PRIVATE SILKWORM_CONSENSUS_TEST_DIR="${CMAKE_SOURCE_DIR}/tests")
target_link_libraries(consensus PRIVATE silkworm_core nlohmann_json::nlohmann_json Boost::filesystem)

# Benchmarks
find_package(benchmark CONFIG REQUIRED)
add_executable(benchmark_precompile benchmark_precompile.cpp)
target_link_libraries(benchmark_precompile silkworm_core benchmark::benchmark)

endif(NOT SILKWORM_CORE_ONLY)
44 changes: 25 additions & 19 deletions core/silkworm/common/util.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 The Silkworm Authors
Copyright 2020-2021 The Silkworm Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -24,46 +24,52 @@

namespace silkworm {

ByteView left_pad(ByteView view, size_t min_size) {
ByteView left_pad(ByteView view, size_t min_size, Bytes& buffer) {
if (view.size() >= min_size) {
return view;
}

thread_local Bytes padded;

if (padded.size() < min_size) {
padded.resize(min_size);
if (buffer.size() < min_size) {
buffer.resize(min_size);
} else {
// view & buffer might overlap in memory,
// so we avoid shrinking the buffer prior to the memmove
}

assert(view.size() < min_size);
size_t prefix_len{min_size - view.size()};

std::memmove(padded.data() + prefix_len, view.data(), view.size());
// view & buffer might overlap in memory,
// thus memmove instead of memcpy
std::memmove(buffer.data() + prefix_len, view.data(), view.size());

padded.resize(min_size);
std::fill_n(padded.data(), prefix_len, '\0');
buffer.resize(min_size);
std::memset(buffer.data(), 0, prefix_len);

return padded;
return buffer;
}

ByteView right_pad(ByteView view, size_t min_size) {
ByteView right_pad(ByteView view, size_t min_size, Bytes& buffer) {
if (view.size() >= min_size) {
return view;
}

thread_local Bytes padded;

if (padded.size() < view.size()) {
padded.resize(view.size());
if (buffer.size() < view.size()) {
buffer.resize(view.size());
} else {
// view & buffer might overlap in memory,
// so we avoid shrinking the buffer prior to the memmove
}

std::memmove(padded.data(), view.data(), view.size());
// view & buffer might overlap in memory,
// thus memmove instead of memcpy
std::memmove(buffer.data(), view.data(), view.size());

assert(view.size() < min_size);
padded.resize(view.size());
padded.resize(min_size);
buffer.resize(view.size());
buffer.resize(min_size);

return padded;
return buffer;
}

evmc::address to_address(ByteView bytes) {
Expand Down
22 changes: 11 additions & 11 deletions core/silkworm/common/util.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 The Silkworm Authors
Copyright 2020-2021 The Silkworm Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,23 +28,23 @@

namespace silkworm {

// If a given view is shorter than min_size,
// If a given string is shorter than min_size,
// pads it to the left with 0s up to min_size.
// Otherwise returns unmodified view.
// Otherwise returns unmodified string.
//
// Might return a view of a thread-local buffer,
// Might return a view of the supplied buffer,
// which must be consumed prior to the next invocation.
// However, the same view may be padded repeatedly.
ByteView left_pad(ByteView view, size_t min_size);
// However, an already padded view may be padded again.
ByteView left_pad(ByteView view, size_t min_size, Bytes& buffer);

// If a given view is shorter than min_size,
// If a given string is shorter than min_size,
// pads it to the right with 0s up to min_size.
// Otherwise returns unmodified view.
// Otherwise returns unmodified string.
//
// Might return a view of a thread-local buffer,
// Might return a view of the supplied buffer,
// which must be consumed prior to the next invocation.
// However, the same view may be padded repeatedly.
ByteView right_pad(ByteView view, size_t min_size);
// However, an already padded view may be padded again.
ByteView right_pad(ByteView view, size_t min_size, Bytes& buffer);

// Converts bytes to evmc::address; input is cropped if necessary.
// Short inputs are left-padded with 0s.
Expand Down
20 changes: 11 additions & 9 deletions core/silkworm/common/util_test.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 The Silkworm Authors
Copyright 2020-2021 The Silkworm Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -21,24 +21,26 @@
namespace silkworm {

TEST_CASE("Padding") {
CHECK(to_hex(right_pad(*from_hex("a5"), 3)) == "a50000");
CHECK(to_hex(right_pad(*from_hex("5a0b54d5dc17e0aadc383d2db4"), 3)) == "5a0b54d5dc17e0aadc383d2db4");
Bytes buffer;

CHECK(to_hex(left_pad(*from_hex("a5"), 3)) == "0000a5");
CHECK(to_hex(left_pad(*from_hex("5a0b54d5dc17e0aadc383d2db4"), 3)) == "5a0b54d5dc17e0aadc383d2db4");
CHECK(to_hex(right_pad(*from_hex("a5"), 3, buffer)) == "a50000");
CHECK(to_hex(right_pad(*from_hex("5a0b54d5dc17e0aadc383d2db4"), 3, buffer)) == "5a0b54d5dc17e0aadc383d2db4");

ByteView repeatedly_padded{right_pad(*from_hex("b8c4"), 3)};
CHECK(to_hex(left_pad(*from_hex("a5"), 3, buffer)) == "0000a5");
CHECK(to_hex(left_pad(*from_hex("5a0b54d5dc17e0aadc383d2db4"), 3, buffer)) == "5a0b54d5dc17e0aadc383d2db4");

ByteView repeatedly_padded{right_pad(*from_hex("b8c4"), 3, buffer)};
CHECK(to_hex(repeatedly_padded) == "b8c400");
repeatedly_padded.remove_prefix(1);
CHECK(to_hex(repeatedly_padded) == "c400");
repeatedly_padded = right_pad(repeatedly_padded, 4);
repeatedly_padded = right_pad(repeatedly_padded, 4, buffer);
CHECK(to_hex(repeatedly_padded) == "c4000000");

repeatedly_padded = left_pad(*from_hex("b8c4"), 3);
repeatedly_padded = left_pad(*from_hex("b8c4"), 3, buffer);
CHECK(to_hex(repeatedly_padded) == "00b8c4");
repeatedly_padded.remove_suffix(1);
CHECK(to_hex(repeatedly_padded) == "00b8");
repeatedly_padded = left_pad(repeatedly_padded, 4);
repeatedly_padded = left_pad(repeatedly_padded, 4, buffer);
CHECK(to_hex(repeatedly_padded) == "000000b8");
}

Expand Down
18 changes: 11 additions & 7 deletions core/silkworm/execution/precompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ static intx::uint256 mult_complexity(const intx::uint256& x) noexcept {
}

uint64_t expmod_gas(ByteView input, evmc_revision) noexcept {
input = right_pad(input, 3 * 32);
Bytes buffer;
input = right_pad(input, 3 * 32, buffer);

intx::uint256 base_len256{intx::be::unsafe::load<intx::uint256>(&input[0])};
intx::uint256 exp_len256{intx::be::unsafe::load<intx::uint256>(&input[32])};
Expand All @@ -126,10 +127,10 @@ uint64_t expmod_gas(ByteView input, evmc_revision) noexcept {

intx::uint256 exp_head{0}; // first 32 bytes of the exponent
if (input.length() > base_len64) {
ByteView exp_input{right_pad(input.substr(base_len64), 32)};
ByteView exp_input{right_pad(input.substr(base_len64), 32, buffer)};
if (exp_len64 < 32) {
exp_input = exp_input.substr(0, exp_len64);
exp_input = left_pad(exp_input, 32);
exp_input = left_pad(exp_input, 32, buffer);
}
exp_head = intx::be::unsafe::load<intx::uint256>(exp_input.data());
}
Expand All @@ -156,7 +157,8 @@ uint64_t expmod_gas(ByteView input, evmc_revision) noexcept {
}

std::optional<Bytes> expmod_run(ByteView input) noexcept {
input = right_pad(input, 3 * 32);
Bytes buffer;
input = right_pad(input, 3 * 32, buffer);

uint64_t base_len{endian::load_big_u64(&input[24])};
input.remove_prefix(32);
Expand All @@ -171,7 +173,7 @@ std::optional<Bytes> expmod_run(ByteView input) noexcept {
return Bytes{};
}

input = right_pad(input, base_len + exponent_len + modulus_len);
input = right_pad(input, base_len + exponent_len + modulus_len, buffer);

mpz_t base;
mpz_init(base);
Expand Down Expand Up @@ -223,7 +225,8 @@ std::optional<Bytes> expmod_run(ByteView input) noexcept {
uint64_t bn_add_gas(ByteView, evmc_revision rev) noexcept { return rev >= EVMC_ISTANBUL ? 150 : 500; }

std::optional<Bytes> bn_add_run(ByteView input) noexcept {
input = right_pad(input, 128);
Bytes buffer;
input = right_pad(input, 128, buffer);

snark::init_libff();

Expand All @@ -244,7 +247,8 @@ std::optional<Bytes> bn_add_run(ByteView input) noexcept {
uint64_t bn_mul_gas(ByteView, evmc_revision rev) noexcept { return rev >= EVMC_ISTANBUL ? 6'000 : 40'000; }

std::optional<Bytes> bn_mul_run(ByteView input) noexcept {
input = right_pad(input, 96);
Bytes buffer;
input = right_pad(input, 96, buffer);

snark::init_libff();

Expand Down
2 changes: 1 addition & 1 deletion libff
Submodule libff updated from 69fa1e to cdfac4