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

Upgrade evmc and evmone libraries #233

Merged
merged 1 commit into from
Sep 22, 2023
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
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ find_library(GTEST_MAIN_LIBRARY gtest_main REQUIRED)
find_package(benchmark REQUIRED)
find_library(LUA_LIBRARY lua REQUIRED)
find_library(KECCAK_LIBRARY keccak REQUIRED)
find_library(EVMC_HEX_LIBRARY hex REQUIRED)
find_library(EVMC_INSTRUCTIONS_LIBRARY evmc-instructions REQUIRED)
find_library(EVMONE_LIBRARY evmone REQUIRED)
find_library(JSON_LIBRARY libjsoncpp.a jsoncpp REQUIRED)
Expand Down
29 changes: 17 additions & 12 deletions scripts/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -134,25 +134,30 @@ make -j$CPUS
$SUDO make install
cd ../..

wget https://github.com/ethereum/evmc/archive/eda05c6866ac06bd93d62b605cbec5839d85c221.zip
rm -rf evmc-eda05c6866ac06bd93d62b605cbec5839d85c221
unzip eda05c6866ac06bd93d62b605cbec5839d85c221.zip
rm eda05c6866ac06bd93d62b605cbec5839d85c221.zip
cd evmc-eda05c6866ac06bd93d62b605cbec5839d85c221
# NOTE: evmc v10.0.0 requires evmone v0.9.0
# evmc v10.1.1 requires evmone v0.10.0 (which requires c++20)
EVMC_VER=10.0.0
wget https://github.com/ethereum/evmc/archive/refs/tags/v${EVMC_VER}.zip
rm -rf evmc-${EVMC_VER}
unzip v${EVMC_VER}.zip
rm v${EVMC_VER}.zip
cd evmc-${EVMC_VER}
mkdir build
cd build
cmake ..
make -j$CPUS
$SUDO make install
cd ../..

wget https://github.com/ethereum/evmone/archive/be870917e8cefd2b125bd27375dd9d2409ff1f68.zip
rm -rf evmone-be870917e8cefd2b125bd27375dd9d2409ff1f68
unzip be870917e8cefd2b125bd27375dd9d2409ff1f68.zip
rm be870917e8cefd2b125bd27375dd9d2409ff1f68.zip
cd evmone-be870917e8cefd2b125bd27375dd9d2409ff1f68
# NOTE: updating evmone to v0.10.0 requires c++20
EVMONE_VER=0.9.1
wget https://github.com/ethereum/evmone/archive/refs/tags/v${EVMONE_VER}.zip
rm -rf evmone-${EVMONE_VER}
unzip v${EVMONE_VER}.zip
rm v${EVMONE_VER}.zip
cd evmone-${EVMONE_VER}
rm -rf evmc
mv ../evmc-eda05c6866ac06bd93d62b605cbec5839d85c221 ./evmc
mv ../evmc-${EVMC_VER} ./evmc
mkdir ./evmc/.git
if [[ "$OSTYPE" == "darwin"* ]]; then
# Mac Silicon: clang 'ar' does not allow empty member list, fails w/ -DBUILD_SHARED_LIBS=OFF
Expand All @@ -164,7 +169,7 @@ cmake --build build --parallel
cd build
$SUDO make install
cd ../..
rm -rf evmone-be870917e8cefd2b125bd27375dd9d2409ff1f68
rm -rf evmone-${EVMONE_VER}

wget https://github.com/chfast/ethash/archive/e3e002ecc25ca699349aa62fa38e7b7cc5f653af.zip
rm -rf ethash-e3e002ecc25ca699349aa62fa38e7b7cc5f653af
Expand Down
1 change: 0 additions & 1 deletion src/parsec/agent/runners/evm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ add_library(evm_runner address.cpp

target_link_libraries(evm_runner parsec
${KECCAK_LIBRARY}
${EVMC_HEX_LIBRARY}
${EVMONE_LIBRARY}
${EVMC_INSTRUCTIONS_LIBRARY})
30 changes: 19 additions & 11 deletions src/parsec/agent/runners/evm/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,14 @@ namespace cbdc::parsec::agent::runner {

auto modified = acc.m_modified.find(key) != acc.m_modified.end();
if(!ret_val.has_value()) {
if(prev_value == value) {
ret_val = EVMC_STORAGE_UNCHANGED;
if(prev_value == value || modified) {
// NOTE: both unchanged value and modifying previously
// added/modified value cases belong in the same group
// related to minimal gas cost of only accessing warm storage.
// See evmc.h for more details.
ret_val = EVMC_STORAGE_ASSIGNED;
} else if(evmc::is_zero(value) && !modified) {
ret_val = EVMC_STORAGE_DELETED;
} else if(modified) {
ret_val = EVMC_STORAGE_MODIFIED_AGAIN;
} else {
ret_val = EVMC_STORAGE_MODIFIED;
acc.m_modified.insert(key);
Expand Down Expand Up @@ -212,14 +214,16 @@ namespace cbdc::parsec::agent::runner {
return n;
}

void evm_host::selfdestruct(const evmc::address& addr,
const evmc::address& beneficiary) noexcept {
auto evm_host::selfdestruct(const evmc::address& addr,
const evmc::address& beneficiary) noexcept
-> bool {
m_log->trace("EVM selfdestruct:", to_hex(addr), to_hex(beneficiary));
// TODO: delete storage keys and code
transfer(addr, beneficiary, evmc::uint256be{});
return true;
}

auto evm_host::create(const evmc_message& msg) noexcept -> evmc::result {
auto evm_host::create(const evmc_message& msg) noexcept -> evmc::Result {
auto maybe_sender_acc = get_account(msg.sender, false);
assert(maybe_sender_acc.has_value());
auto& sender_acc = maybe_sender_acc.value();
Expand Down Expand Up @@ -293,7 +297,7 @@ namespace cbdc::parsec::agent::runner {
return res;
}

auto evm_host::call(const evmc_message& msg) noexcept -> evmc::result {
auto evm_host::call(const evmc_message& msg) noexcept -> evmc::Result {
if(msg.kind == EVMC_CREATE2 || msg.kind == EVMC_CREATE) {
return create(msg);
}
Expand All @@ -315,8 +319,10 @@ namespace cbdc::parsec::agent::runner {
const auto code_size = get_code_size(code_addr);
if(code_size == 0) {
// TODO: deduct simple send fixed gas amount
const auto gas_refund = 0;
auto res = evmc::make_result(evmc_status_code::EVMC_SUCCESS,
msg.gas,
gas_refund,
nullptr,
0);

Expand All @@ -326,7 +332,7 @@ namespace cbdc::parsec::agent::runner {
m_receipt.m_success = true;
}

return evmc::result(res);
return evmc::Result(res);
}

auto code_buf = std::vector<uint8_t>(code_size);
Expand Down Expand Up @@ -729,17 +735,19 @@ namespace cbdc::parsec::agent::runner {

auto evm_host::execute(const evmc_message& msg,
const uint8_t* code,
size_t code_size) -> evmc::result {
size_t code_size) -> evmc::Result {
// Make VM instance if we didn't already
if(!m_vm) {
m_vm = std::make_unique<evmc::VM>(evmc_create_evmone());
if(!(*m_vm) || !m_vm->is_abi_compatible()) {
m_log->error("Unable to load EVM implementation");
const auto gas_refund = 0;
auto res = evmc::make_result(evmc_status_code::EVMC_FAILURE,
msg.gas,
gas_refund,
nullptr,
0);
return evmc::result(res);
return evmc::Result(res);
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/parsec/agent/runners/evm/host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ namespace cbdc::parsec::agent::runner {
size_t buffer_size) const noexcept
-> size_t override final;

void
selfdestruct(const evmc::address& addr,
const evmc::address& beneficiary) noexcept override final;
auto selfdestruct(const evmc::address& addr,
const evmc::address& beneficiary) noexcept
-> bool override final;

auto call(const evmc_message& msg) noexcept
-> evmc::result override final;
-> evmc::Result override final;

[[nodiscard]] auto get_tx_context() const noexcept
-> evmc_tx_context override final;
Expand Down Expand Up @@ -204,11 +204,11 @@ namespace cbdc::parsec::agent::runner {
[[nodiscard]] auto get_key(const cbdc::buffer& key, bool write) const
-> std::optional<broker::value_type>;

auto create(const evmc_message& msg) noexcept -> evmc::result;
auto create(const evmc_message& msg) noexcept -> evmc::Result;

auto execute(const evmc_message& msg,
const uint8_t* code,
size_t code_size) -> evmc::result;
size_t code_size) -> evmc::Result;
};
}

Expand Down
13 changes: 5 additions & 8 deletions tests/unit/parsec/agent/runners/evm/evm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,23 +210,20 @@ TEST_F(evm_test, host_storage) {
EXPECT_EQ(chost.get_storage(addr2, val1), evmc::bytes32{});
EXPECT_EQ(host.set_storage(addr2, val1, val2), EVMC_STORAGE_ADDED);
EXPECT_EQ(chost.get_storage(addr2, val1), val2);
EXPECT_EQ(host.set_storage(addr2, val1, val2), EVMC_STORAGE_UNCHANGED);
EXPECT_EQ(host.set_storage(addr2, val1, val2), EVMC_STORAGE_ASSIGNED);
EXPECT_EQ(chost.get_storage(addr2, val1), val2);
EXPECT_EQ(host.set_storage(addr2, val1, val3),
EVMC_STORAGE_MODIFIED_AGAIN);
EXPECT_EQ(host.set_storage(addr2, val1, val3), EVMC_STORAGE_ASSIGNED);
EXPECT_EQ(chost.get_storage(addr2, val1), val3);
EXPECT_EQ(host.set_storage(addr2, val1, val1),
EVMC_STORAGE_MODIFIED_AGAIN);
EXPECT_EQ(host.set_storage(addr2, val1, val1), EVMC_STORAGE_ASSIGNED);
EXPECT_EQ(chost.get_storage(addr2, val1), val1);

EXPECT_EQ(chost.get_storage(addr2, val3), evmc::bytes32{});
EXPECT_EQ(host.set_storage(addr2, val3, evmc::bytes32{}),
EVMC_STORAGE_UNCHANGED);
EVMC_STORAGE_ASSIGNED);
EXPECT_EQ(chost.get_storage(addr2, val3), evmc::bytes32{});
EXPECT_EQ(host.set_storage(addr2, val3, val3), EVMC_STORAGE_MODIFIED);
EXPECT_EQ(chost.get_storage(addr2, val3), val3);
EXPECT_EQ(host.set_storage(addr2, val3, val1),
EVMC_STORAGE_MODIFIED_AGAIN);
EXPECT_EQ(host.set_storage(addr2, val3, val1), EVMC_STORAGE_ASSIGNED);
EXPECT_EQ(chost.get_storage(addr2, val3), val1);

// Set storage to zero on an existing storage location deletes it
Expand Down
Loading