Skip to content

Commit

Permalink
Merge branch 'main' into arhag/common-mapping-height-timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
arhag committed Mar 14, 2023
2 parents 16c1ae0 + ba6bb61 commit bc3fe83
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ ee cmake --version
ee mkdir -p contract/build
ee pushd contract
ee pushd build
ee "cmake -DCMAKE_BUILD_TYPE=$DCMAKE_BUILD_TYPE -DWITH_TEST_ACTIONS=$DWITH_TEST_ACTIONS .."
ee "cmake -DCMAKE_BUILD_TYPE=$DCMAKE_BUILD_TYPE -DWITH_TEST_ACTIONS=$DWITH_TEST_ACTIONS -DWITH_LARGE_STACK=$DWITH_TEST_ACTIONS .."
ee make -j "$(nproc)"

# pack
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ jobs:
if-no-files-found: error

- name: Download Leap - dev binary
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
uses: AntelopeIO/asset-artifact-download-action@v2
with:
owner: AntelopeIO
Expand All @@ -86,27 +85,24 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Install Leap
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
run: sudo apt-get install -y ./leap*.deb

- name: Build TrustEVM Contract Tests
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
run: .github/workflows/build-contract-test.sh

- name: Upload Artifacts
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
uses: actions/upload-artifact@v3
with:
name: contract-test.tar.gz
path: contract-test.tar.gz
if-no-files-found: error

- name: Test TrustEVM Contract
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
run: .github/workflows/test-contract.sh
env:
DWITH_TEST_ACTIONS: ${{ matrix.DWITH_TEST_ACTIONS }}

- name: Upload Test Metrics
if: matrix.DWITH_TEST_ACTIONS == 'on' || matrix.DWITH_TEST_ACTIONS == 'true'
uses: actions/upload-artifact@v3
with:
name: test-results.xml
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/test-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ function ee()
}

ee pushd contract/tests/build
ee "ctest -j \"$(nproc)\" --output-on-failure -T Test || :"
if [ "$DWITH_TEST_ACTIONS" = "on" ] || [ "$DWITH_TEST_ACTIONS" = "true" ]; then
ee "ctest -R consensus_tests -j \"$(nproc)\" --output-on-failure -T Test"
else
ee "ctest -E consensus_tests -j \"$(nproc)\" --output-on-failure -T Test"
fi

cp "$(find ./Testing -name 'Test.xml' | sort | tail -n '1')" "../../../${XUNIT_FILENAME:-test-results.xml}"
echo "Done! - ${0##*/}"
4 changes: 4 additions & 0 deletions contract/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ option(WITH_TEST_ACTIONS
option(WITH_LOGTIME
"Use `logtime` instrisic to log the time spent in transaction execution" OFF)

option(WITH_LARGE_STACK
"Build with 50MB of stack size, needed for unit tests" OFF)

ExternalProject_Add(
evm_runtime_project
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src
Expand All @@ -21,6 +24,7 @@ ExternalProject_Add(
-DCMAKE_TOOLCHAIN_FILE=${CDT_ROOT}/lib/cmake/cdt/CDTWasmToolchain.cmake
-DWITH_TEST_ACTIONS=${WITH_TEST_ACTIONS}
-DWITH_LOGTIME=${WITH_LOGTIME}
-DWITH_LARGE_STACK=${WITH_LARGE_STACK}
UPDATE_COMMAND ""
PATCH_COMMAND ""
TEST_COMMAND ""
Expand Down
8 changes: 4 additions & 4 deletions contract/include/evm_runtime/evm_contract.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <evm_runtime/types.hpp>

#include <silkworm/types/block.hpp>
#include <silkworm/consensus/engine.hpp>
#include <silkworm/execution/processor.hpp>
#ifdef WITH_TEST_ACTIONS
#include <evm_runtime/test/block_info.hpp>
#endif
Expand Down Expand Up @@ -44,7 +44,7 @@ CONTRACT evm_contract : public contract {
bool gc(uint32_t max);

#ifdef WITH_TEST_ACTIONS
ACTION testtx( const bytes& rlptx, const evm_runtime::test::block_info& bi );
ACTION testtx( const std::optional<bytes>& orlptx, const evm_runtime::test::block_info& bi );
ACTION updatecode( const bytes& address, uint64_t incarnation, const bytes& code_hash, const bytes& code);
ACTION updateaccnt(const bytes& address, const bytes& initial, const bytes& current);
ACTION updatestore(const bytes& address, uint64_t incarnation, const bytes& location, const bytes& initial, const bytes& current);
Expand Down Expand Up @@ -88,8 +88,8 @@ CONTRACT evm_contract : public contract {
check((_config.get().status & static_cast<uint32_t>(status_flags::frozen)) == 0, "contract is frozen");
}

void push_trx(eosio::name ram_payer, silkworm::Block& block, const bytes& rlptx, silkworm::consensus::IEngine& engine, const silkworm::ChainConfig& chain_config);
silkworm::Receipt execute_tx( silkworm::Block& block, const bytes& rlptx, silkworm::ExecutionProcessor& ep );
};


} //evm_runtime
} //evm_runtime
42 changes: 33 additions & 9 deletions contract/include/evm_runtime/print_tracer.hpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,47 @@
#pragma once

#include <evmc/instructions.h>
namespace evm_runtime {

struct print_tracer : EvmTracer {

void on_execution_start(evmc_revision rev, const evmc_message& msg, evmone::bytes_view code) override {
const char* const* opcode_names_ = nullptr;

void on_execution_start(evmc_revision rev, const evmc_message& msg, evmone::bytes_view code) noexcept override {
eosio::print("TRACE: start\n");
};
if (opcode_names_ == nullptr) {
opcode_names_ = evmc_get_instruction_names_table(rev);
}
}

void on_instruction_start(uint32_t pc, const evmone::ExecutionState& state,
const IntraBlockState& intra_block_state) override {
eosio::print("TRACE[inst] ", uint64_t(pc), ": ", uint64_t(state.gas_left), "\n");
std::string get_opcode_name(const char* const* names, std::uint8_t opcode) {
const auto name = names[opcode];
return (name != nullptr) ?name : "opcode 0x" + evmc::hex(opcode) + " not defined";
}

};
void on_instruction_start(uint32_t pc, const intx::uint256* stack_top, int stack_height,
const evmone::ExecutionState& state,
const IntraBlockState& intra_block_state) noexcept override {
const auto opcode = state.code[pc];
auto opcode_name = get_opcode_name(opcode_names_, opcode);
eosio::print(opcode_name.c_str(), "\n");
}

void on_execution_end(const evmc_result& result, const IntraBlockState& intra_block_state) override {
void on_execution_end(const evmc_result& result, const IntraBlockState& intra_block_state) noexcept override {
eosio::print("TRACE: end\n");
}

};
void on_creation_completed(const evmc_result& result, const IntraBlockState& intra_block_state) noexcept override {

}

void on_precompiled_run(const evmc_result& result, int64_t gas,
const IntraBlockState& intra_block_state) noexcept override {

}

void on_reward_granted(const CallResult& result, const IntraBlockState& intra_block_state) noexcept override {

}

};
} //namespace evm_runtime
6 changes: 5 additions & 1 deletion contract/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,8 @@ target_include_directories( evm_runtime PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../../silkworm/third_party/evmone/evmc/include
)

target_link_options(evm_runtime PUBLIC -stack-size=20480)
if (WITH_LARGE_STACK)
target_link_options(evm_runtime PUBLIC --stack-size=50000000)
else()
target_link_options(evm_runtime PUBLIC --stack-size=20480)
endif()
29 changes: 19 additions & 10 deletions contract/src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void check_result( ValidationResult r, const Transaction& txn, const char* desc
eosio::check( false, desc );
}

void evm_contract::push_trx( eosio::name ram_payer, Block& block, const bytes& rlptx, silkworm::consensus::IEngine& engine, const silkworm::ChainConfig& chain_config ) {
Receipt evm_contract::execute_tx( Block& block, const bytes& rlptx, silkworm::ExecutionProcessor& ep ) {

Transaction tx;
ByteView bv{(const uint8_t*)rlptx.data(), rlptx.size()};
Expand All @@ -97,9 +97,6 @@ void evm_contract::push_trx( eosio::name ram_payer, Block& block, const bytes& r
eosio::check(tx.from.has_value(), "unable to recover sender");
LOGTIME("EVM RECOVER SENDER");

evm_runtime::state state{get_self(), ram_payer};
silkworm::ExecutionProcessor ep{block, engine, state, chain_config};

ValidationResult r = consensus::pre_validate_transaction(tx, ep.evm().block().header.number, ep.evm().config(),
ep.evm().block().header.base_fee_per_gas);
check_result( r, tx, "pre_validate_transaction error" );
Expand All @@ -109,10 +106,8 @@ void evm_contract::push_trx( eosio::name ram_payer, Block& block, const bytes& r
Receipt receipt;
ep.execute_transaction(tx, receipt);

engine.finalize(ep.state(), ep.evm().block(), ep.evm().revision());
ep.state().write_to_db(ep.evm().block().header.number);

LOGTIME("EVM EXECUTE");
return receipt;
}

void evm_contract::pushtx( eosio::name ram_payer, const bytes& rlptx ) {
Expand All @@ -132,7 +127,14 @@ void evm_contract::pushtx( eosio::name ram_payer, const bytes& rlptx ) {
block.header.timestamp = bm.evm_block_num_to_evm_timestamp(block.header.number);

silkworm::consensus::TrustEngine engine{*found_chain_config->second};
push_trx( ram_payer, block, rlptx, engine, *found_chain_config->second );

evm_runtime::state state{get_self(), ram_payer};
silkworm::ExecutionProcessor ep{block, engine, state, *found_chain_config->second};

auto receipt = execute_tx(block, rlptx, ep);

engine.finalize(ep.state(), ep.evm().block(), ep.evm().revision());
ep.state().write_to_db(ep.evm().block().header.number);
}

void evm_contract::open(eosio::name owner, eosio::name ram_payer) {
Expand Down Expand Up @@ -201,7 +203,7 @@ bool evm_contract::gc(uint32_t max) {
}

#ifdef WITH_TEST_ACTIONS
ACTION evm_contract::testtx( const bytes& rlptx, const evm_runtime::test::block_info& bi ) {
ACTION evm_contract::testtx( const std::optional<bytes>& orlptx, const evm_runtime::test::block_info& bi ) {
assert_unfrozen();

eosio::require_auth(get_self());
Expand All @@ -210,7 +212,14 @@ ACTION evm_contract::testtx( const bytes& rlptx, const evm_runtime::test::block_
block.header = bi.get_block_header();

evm_runtime::test::engine engine;
push_trx( get_self(), block, rlptx, engine, evm_runtime::test::kTestNetwork );
evm_runtime::state state{get_self(), get_self()};
silkworm::ExecutionProcessor ep{block, engine, state, evm_runtime::test::kTestNetwork};

if(orlptx) {
execute_tx(block, *orlptx, ep);
}
engine.finalize(ep.state(), ep.evm().block(), ep.evm().revision());
ep.state().write_to_db(ep.evm().block().header.number);
}

ACTION evm_contract::dumpstorage(const bytes& addy) {
Expand Down
56 changes: 35 additions & 21 deletions contract/src/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,34 +90,48 @@ void state::update_account(const evmc::address& address, std::optional<Account>
auto itr = inx.find(make_key(address));
++stats.account.read;

auto emplace = [&](auto& row) {
row.id = accounts.available_primary_key();
row.eth_address = to_bytes(address);
row.nonce = current->nonce;
row.balance = to_bytes(current->balance);
row.code_hash = to_bytes(current->code_hash);
};

auto update = [&](auto& row) {
row.nonce = current->nonce;
row.balance = to_bytes(current->balance);
row.code_hash = to_bytes(current->code_hash);
};

auto remove_account = [&](auto& itr) {
storage_table db(_self, itr->id);
// add to garbage collection table for later removal
gc_store_table gc(_self, _self.value);
gc.emplace(_ram_payer, [&](auto& row){
row.id = gc.available_primary_key();
row.storage_id = itr->id;
});
accounts.erase(*itr);
};


if (current.has_value()) {
if (itr == inx.end()) {
accounts.emplace(_ram_payer, [&](auto& row){
row.id = accounts.available_primary_key();
row.eth_address = to_bytes(address);
row.nonce = current->nonce;
row.balance = to_bytes(current->balance);
row.code_hash = to_bytes(current->code_hash);
});
accounts.emplace(_ram_payer, emplace);
++stats.account.create;
} else {
accounts.modify(*itr, eosio::same_payer, [&](auto& row){
row.nonce = current->nonce;
row.code_hash = to_bytes(current->code_hash);
row.balance = to_bytes(current->balance);
});
++stats.account.update;
if( initial && initial->incarnation != current->incarnation ) {
remove_account(itr);
accounts.emplace(_ram_payer, emplace);
} else {
accounts.modify(*itr, eosio::same_payer, update);
++stats.account.update;
}
}
} else {
if(itr != inx.end()) {
storage_table db(_self, itr->id);
// add to garbage collection table for later removal
gc_store_table gc(_self, _self.value);
gc.emplace(_ram_payer, [&](auto& row){
row.id = gc.available_primary_key();
row.storage_id = itr->id;
});
accounts.erase(*itr);
remove_account(itr);
++stats.account.remove;
}
}
Expand Down
5 changes: 4 additions & 1 deletion contract/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ add_eosio_test_executable( unit_test
${CMAKE_SOURCE_DIR}/../external/ethash/lib/ethash/primes.c
)

add_test(NAME unit_test COMMAND unit_test --report_level=detailed --color_output -- --eos-vm-oc)
# TODO: add back eos-vm-oc once change to disable EOS VM OC subjective limits during unit test are added
add_test(NAME consensus_tests COMMAND unit_test --report_level=detailed --color_output --run_test=evm_runtime_tests)

add_test(NAME unit_tests COMMAND unit_test --report_level=detailed --color_output --run_test=!evm_runtime_tests)
Loading

0 comments on commit bc3fe83

Please sign in to comment.