Skip to content
Draft
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@
[submodule "src/xtopcom/xdepends/xquic"]
path = src/xtopcom/xdepends/xquic
url = git@github.com:telosprotocol/xquic.git
[submodule "src/xtopcom/xtvm_engine_rs"]
path = src/xtopcom/xtvm_engine_rs
url = git@github.com:telosprotocol/tvm_engine_rs.git
2 changes: 2 additions & 0 deletions src/xtopcom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,5 @@ if (XBUILD_CONSORTIUM)
endif()

add_subdirectory(xstatistic)
add_subdirectory(xtvm_engine_rs)
add_subdirectory(xtvm_runtime)
5 changes: 3 additions & 2 deletions src/xtopcom/xdata/src/xtop_action_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ std::unique_ptr<data::xbasic_top_action_t const> xtop_action_generator::generate
case base::enum_vaccount_addr_type_native_contract:
// just for followup transfer tx
case base::enum_vaccount_addr_type_secp256k1_user_account:
case base::enum_vaccount_addr_type_secp256k1_eth_user_account:
return top::make_unique<data::xsystem_consensus_action_t>(tx);


// T8 address use for tvm (solidity tx)
case base::enum_vaccount_addr_type_secp256k1_eth_user_account:
case base::enum_vaccount_addr_type_secp256k1_evm_user_account:
return top::make_unique<data::xevm_consensus_action_t>(tx);

Expand Down
2 changes: 2 additions & 0 deletions src/xtopcom/xevm_common/xevm_transaction_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class xevm_log_t {
using xevm_logs_t = std::vector<xevm_log_t>;

/// same as TransactionStatus in `evm_engine_rs/engine/src/parameters.rs`
// 23.02.22 future update to: `xtvm_engine_rs/tvm-engine/src/types.rs`
enum xevm_transaction_status_t : uint32_t {
Success = 0,
Revert = 1,
Expand All @@ -54,6 +55,7 @@ enum xevm_transaction_status_t : uint32_t {
OtherExecuteError = 5,

Invalid = 32,
FAILED = UINT32_MAX,
};

class xevm_transaction_result_t {
Expand Down
6 changes: 6 additions & 0 deletions src/xtopcom/xstate_accessor/src/xstate_accessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,12 @@ void xtop_state_accessor::clear_property(properties::xproperty_identifier_t cons
return;
}

// should check if property exist, the below code `bstate_->load_xxx` has `xerror()` if not exist.
if (!bstate_->find_property(property_id.full_name())) {
ec = error::xerrc_t::property_not_exist;
return;
}

switch (property_id.type()) {
case properties::xproperty_type_t::map:
{
Expand Down
1 change: 1 addition & 0 deletions src/xtopcom/xtvm_engine_rs
Submodule xtvm_engine_rs added at 10013a
13 changes: 13 additions & 0 deletions src/xtopcom/xtvm_runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
add_compile_options(-Wpedantic)

aux_source_directory(./src src_dir)
add_library(xtvm_runtime STATIC ${src_dir})

add_dependencies(xtvm_runtime tvm_engine)
get_target_property(TVM_ENGINE_DIR tvm_engine LOCATION)
target_link_libraries(xtvm_runtime PRIVATE ${TVM_ENGINE_DIR}/libtvm_engine.a)
target_include_directories(xtvm_runtime PRIVATE ${CMAKE_SOURCE_DIR}/src/xtopcom/xtvm_engine_rs/tvm-c-api)

add_dependencies(xtvm_runtime xstate_accessor xevm_common xbasic xcommon)

target_link_libraries(xtvm_runtime PRIVATE tvm-c-api xstate_accessor xevm_common xbasic xcommon protobuf)
48 changes: 48 additions & 0 deletions src/xtopcom/xtvm_runtime/src/xerror.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2017-present Telos Foundation & contributors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "xtvm_runtime/xerror.h"

NS_BEG3(top, tvm, error)

static char const * const errc_to_string(int code) {
auto const ec = static_cast<xerrc_t>(code);

switch (ec) {
case xerrc_t::ok:
return "ok";

case xerrc_t::protobuf_serilized_error:
return "protobuf error";

default:
return "unknown tvm runtime error";
}
}

std::error_code make_error_code(xerrc_t const errc) noexcept {
return std::error_code(static_cast<int>(errc), tvm_category());
}

std::error_condition make_error_condition(xerrc_t const errc) noexcept {
return std::error_condition(static_cast<int>(errc), tvm_category());
}

class xtop_tvm_category final : public std::error_category {
char const * name() const noexcept override {
return "tvm";
}

std::string message(int errc) const override {
return errc_to_string(errc);
}
};
using xtvm_category_t = xtop_tvm_category;

std::error_category const & tvm_category() {
static xtvm_category_t category{};
return category;
}

NS_END3
48 changes: 48 additions & 0 deletions src/xtopcom/xtvm_runtime/src/xtvm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2017-present Telos Foundation & contributors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "xtvm_runtime/xtvm.h"

#include "xdata/xtop_action.h"
#include "xdata/xtop_action_generator.h"
#include "xtvm_runtime/xtvm_action_runner.h"
#include "xtvm_runtime/xtvm_context.h"

NS_BEG2(top, tvm)

xtop_vm::xtop_vm(statectx::xstatectx_face_ptr_t const statectx) : m_statectx{statectx} {
}

txexecutor::enum_execute_result_type xtop_vm::execute(txexecutor::xvm_input_t const & input, txexecutor::xvm_output_t & output) {
m_statectx = input.get_statectx();
auto action = contract_runtime::xaction_generator_t::generate(input.get_tx());

evm_common::xevm_transaction_result_t action_result;

try {
action_result = execute_action(std::move(action), input.get_para());
} catch (top::error::xtop_error_t & eh) {
// should be implment bug here:
xerror("tvm: caught error: %s %s", eh.category().name(), eh.what());
} catch (std::exception const & eh) {
xerror("tvm: caught unknown exception: %s", eh.what());
}

output.m_tx_result = action_result;
if (action_result.status == evm_common::xevm_transaction_status_t::FAILED) {
return txexecutor::enum_exec_error_vm_execute;
}
return txexecutor::enum_exec_success;
}

evm_common::xevm_transaction_result_t xtop_vm::execute_action(std::unique_ptr<data::xbasic_top_action_t const> action, txexecutor::xvm_para_t const & vm_para) {
// 1. build action runtime context with action and vm_para
auto vm_context = top::make_unique<xtvm_context_t>(std::move(action), vm_para);

// 2. run action runtime on this context, return `evm_common::xevm_transaction_result_t`
auto vm_runner = xtvm_action_runner_t{m_statectx};
return vm_runner.execute_action(std::move(vm_context));
}

NS_END2
63 changes: 63 additions & 0 deletions src/xtopcom/xtvm_runtime/src/xtvm_action_runner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2017-present Telos Foundation & contributors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "xtvm_runtime/xtvm_action_runner.h"

#include "protobuf_types/pparameters.pb.h"
#include "xcommon/xeth_address.h"
#include "xcontract_runtime/xerror/xerror.h"
#include "xtvm_engine_rs/tvm-c-api/tvm_engine_interface.h"
#include "xtvm_engine_rs/tvm-c-api/tvm_import_instance.h"
#include "xtvm_runtime/xerror.h"
#include "xtvm_runtime/xtvm_logic.h"
#include "xtvm_runtime/xtvm_storage.h"

NS_BEG2(top, tvm)

xtop_vm_action_runner::xtop_vm_action_runner(statectx::xstatectx_face_ptr_t const statectx) : m_statectx{statectx} {
}

evm_common::xevm_transaction_result_t xtop_vm_action_runner::execute_action(std::unique_ptr<xtvm_context_t> context) {
evm_common::xevm_transaction_result_t result;

auto storage = top::make_unique<xtvm_storage_t>(m_statectx);
std::shared_ptr<xtvm_logic_t> logic_ptr = std::make_shared<xtvm_logic_t>(top::make_observer(storage.get()), top::make_observer(context.get()));

tvm_import_instance::instance()->add_logic(logic_ptr);

// call vm engine in rust.
bool bool_result = call();

// fetch result
auto return_result_bytes = logic_ptr->get_return_value();

xinfo("xtop_vm_action_runner::execute_action result %s return_bytes_size: %zu", bool_result ? "success" : "fail", return_result_bytes.size());

tvm_import_instance::instance()->remove_logic();

tvm_engine::parameters::PReturnResult return_result;
auto ret = return_result.ParseFromString(top::to_string(return_result_bytes));

if (!ret) {
top::error::throw_error(top::tvm::error::xerrc_t::protobuf_serilized_error);
}
result.set_status(return_result.status());
result.extra_msg = top::to_hex_prefixed(return_result.status_data());
result.used_gas = return_result.gas_used();
// logs:
for (int i = 0; i < return_result.logs_size(); ++i) {
common::xeth_address_t address = common::xeth_address_t::build_from(top::to_bytes(return_result.logs(i).address().value()));
xbytes_t data = top::to_bytes(return_result.logs(i).data());
evm_common::xh256s_t topics;
for (int j = 0; j < return_result.logs(i).topics_size(); ++j) {
topics.push_back(evm_common::xh256_t(top::to_bytes(return_result.logs(i).topics(j).data())));
}
evm_common::xevm_log_t log(address, topics, data);
result.logs.push_back(log);
}

return result;
}

NS_END2
89 changes: 89 additions & 0 deletions src/xtopcom/xtvm_runtime/src/xtvm_context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2017-present Telos Foundation & contributors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "xtvm_runtime/xtvm_context.h"

#include "xbasic/xhex.h"
#include "xdata/xconsensus_action.h"
// xtvm_engine_rs/tvm-c-api/
#include "protobuf_types/pbasic.pb.h"
#include "protobuf_types/pparameters.pb.h"

NS_BEG2(top, tvm)

// static const uint32_t CURRENT_CALL_ARGS_VERSION = 1;

xtop_vm_context::xtop_vm_context(std::unique_ptr<data::xbasic_top_action_t const> action, txexecutor::xvm_para_t const & vm_para) : m_action{std::move(action)} {
// common usage:
assert(m_action->type() == data::xtop_action_type_t::evm);

// gas_limit:
auto gas_limit = static_cast<data::xevm_consensus_action_t const *>(m_action.get())->gas_limit();

// action_type:
// we don't really need to sense this, should also be deleted in `action`
// m_action_type = static_cast<data::xevm_consensus_action_t const *>(m_action.get())->evm_action_type();

// todo! gas price
// m_gas_price = 0;

// sender:
assert(m_action->type() == data::xtop_action_type_t::evm);
m_sender = static_cast<data::xevm_consensus_action_t const *>(m_action.get())->sender();

// recver:
auto m_recver = static_cast<data::xevm_consensus_action_t const *>(m_action.get())->recver();

// block_height:
m_block_height = vm_para.get_block_height();

// coinbase:
m_coinbase = vm_para.get_block_coinbase();

// block ts:
m_block_timestamp = vm_para.get_timestamp();

// chain_id;
m_chain_id = XGET_CONFIG(chain_id);

// input_data;
top::tvm_engine::parameters::PCallArgs call_args;
call_args.set_gas_limit(gas_limit);
call_args.set_input(top::to_string(static_cast<data::xevm_consensus_action_t const *>(m_action.get())->data()));
auto sender_address = call_args.mutable_sender_address();
sender_address->set_value(top::to_string(top::from_hex(m_sender.to_string().substr(6))));
auto recver_address = call_args.mutable_recver_address();
recver_address->set_value(top::to_string(top::from_hex(m_recver.to_string().substr(6))));
evm_common::u256 value_u256 = static_cast<data::xevm_consensus_action_t const *>(m_action.get())->value(); // utop , should not bigger than U256
uint64_t value_u64 = value_u256.convert_to<uint64_t>();
call_args.set_value(value_u64);
m_input_data = top::to_bytes(call_args.SerializeAsString());
}

// data::xtop_evm_action_type xtop_vm_context::action_type() const{
// return m_action_type;
// }
xbytes_t const & xtop_vm_context::input_data() const {
return m_input_data;
}
uint64_t xtop_vm_context::gas_price() const {
return m_gas_price;
}
common::xaccount_address_t xtop_vm_context::sender() const {
return m_sender;
}
uint64_t xtop_vm_context::block_height() const {
return m_block_height;
}
common::xaccount_address_t xtop_vm_context::coinbase() const {
return m_coinbase;
}
uint64_t xtop_vm_context::block_timestamp() const {
return m_block_timestamp;
}
uint64_t xtop_vm_context::chain_id() const {
return m_chain_id;
}

NS_END2
Loading