Skip to content

Set config in tvm_emulator_emulate_run_method and add separate method to read VM logs #1655

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

Open
wants to merge 2 commits into
base: testnet
Choose a base branch
from
Open
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
70 changes: 63 additions & 7 deletions emulator/emulator-extern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,10 +639,16 @@ const char *tvm_emulator_run_get_method(void *tvm_emulator, int method_id, const
return strdup(jb.string_builder().as_cslice().c_str());
}

const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc, int64_t gas_limit) {
struct TvmEulatorEmulateRunMethodResponse
{
const char *response;
const char *log;
};

TvmEulatorEmulateRunMethodResponse emulate_run_method(uint32_t len, const char *params_boc, int64_t gas_limit) {
auto params_cell = vm::std_boc_deserialize(td::Slice(params_boc, len));
if (params_cell.is_error()) {
return nullptr;
return { nullptr, nullptr };
}
auto params_cs = vm::load_cell_slice(params_cell.move_as_ok());
auto code = params_cs.fetch_ref();
Expand All @@ -657,12 +663,12 @@ const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc

td::Ref<vm::Stack> stack;
if (!vm::Stack::deserialize_to(stack_cs, stack)) {
return nullptr;
return { nullptr, nullptr };
}

td::Ref<vm::Stack> c7;
if (!vm::Stack::deserialize_to(c7_cs, c7)) {
return nullptr;
return { nullptr, nullptr };
}

auto emulator = new emulator::TvmEmulator(code, data);
Expand All @@ -672,12 +678,43 @@ const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc
if (!libs.is_empty()) {
emulator->set_libraries(std::move(libs));
}

if (c7->depth() > 0) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could linearize this logic with goto, but I have not found usage of this operator in code, and considering controversial nature of it, I've decided to not use it.

vm::StackEntry c7_stack = c7->fetch(0);
if (!c7_stack.is_null() && c7_stack.is_tuple()) {
td::Ref<vm::Tuple> c7_root = c7_stack.as_tuple();
if (!c7_root.is_null()) {
vm::StackEntry c7_top = tuple_index(c7_root, 0);
if (!c7_top.is_null() && c7_top.is_tuple()) {
td::Ref<vm::Tuple> c7_top_tuple = c7_top.as_tuple();
if (!c7_top_tuple.is_null()) {
vm::StackEntry config_entry = tuple_index(c7_top_tuple, 9);
if (!config_entry.is_null() && config_entry.is_cell() && config_entry.as_cell().not_null()) {
vm::CellSlice config_cell_slice = vm::load_cell_slice(config_entry.as_cell());
if (config_cell_slice.size() > 0) {
block::Config config(config_entry.as_cell(), td::Bits256::zero(),
block::Config::needWorkchainInfo | block::Config::needSpecialSmc | block::Config::needCapabilities);
auto config_ptr = std::make_shared<block::Config>(std::move(config));
td::Status unpack_res = config_ptr->unpack();
if (unpack_res.is_error()) {
LOG(ERROR) << "Can't unpack config params";
return { nullptr, nullptr };
}
emulator->set_config(config_ptr);
}
}
}
}
}
}
}

auto result = emulator->run_get_method(int(method_id), stack);
delete emulator;

vm::CellBuilder stack_cb;
if (!result.stack->serialize(stack_cb)) {
return nullptr;
return { nullptr, nullptr };
}

vm::CellBuilder cb;
Expand All @@ -687,7 +724,7 @@ const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc

auto ser = vm::std_boc_serialize(cb.finalize());
if (!ser.is_ok()) {
return nullptr;
return { nullptr, nullptr };
}
auto sok = ser.move_as_ok();

Expand All @@ -696,7 +733,26 @@ const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc
memcpy(rn, &sz, 4);
memcpy(rn+4, sok.data(), sz);

return rn;
auto log_sz = uint32_t(result.vm_log.size());
char* log_buffer = (char*)malloc(log_sz + 4);
memcpy(log_buffer, &log_sz, 4);
memcpy(log_buffer+4, result.vm_log.data(), log_sz);

return { rn, log_buffer };
}

const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc, int64_t gas_limit) {
auto result = emulate_run_method(len, params_boc, gas_limit);
return result.response;
}

const char *tvm_emulator_emulate_run_method_detailed(uint32_t len, const char *params_boc, int64_t gas_limit) {
auto result = emulate_run_method(len, params_boc, gas_limit);
TvmEulatorEmulateRunMethodResponse* response_ptr =
(TvmEulatorEmulateRunMethodResponse*)malloc(sizeof(TvmEulatorEmulateRunMethodResponse));
response_ptr->response = result.response;
response_ptr->log = result.log;
return reinterpret_cast<const char*>(response_ptr);
}

const char *tvm_emulator_send_external_message(void *tvm_emulator, const char *message_body_boc) {
Expand Down
12 changes: 12 additions & 0 deletions emulator/emulator-extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,18 @@ EMULATOR_EXPORT const char *tvm_emulator_run_get_method(void *tvm_emulator, int
*/
EMULATOR_EXPORT const char *tvm_emulator_emulate_run_method(uint32_t len, const char *params_boc, int64_t gas_limit);

/**
* @brief Optimized version of "run get method" with all passed parameters in a single call. Also returns log.
* @param len Length of params_boc buffer
* @param params_boc BoC serialized parameters, scheme: request$_ code:^Cell data:^Cell stack:^VmStack params:^[c7:^VmStack libs:^Cell] method_id:(## 32)
* @param gas_limit Gas limit
* @return Struct with two fields:
* - response: Char* with first 4 bytes defining length, and the rest BoC serialized result
* Scheme: result$_ exit_code:(## 32) gas_used:(## 32) stack:^VmStack
* - log: Char* with first 4 bytes defining length, and the rest is log
*/
EMULATOR_EXPORT const char *tvm_emulator_emulate_run_method_detailed(uint32_t len, const char *params_boc, int64_t gas_limit);

/**
* @brief Send external message
* @param tvm_emulator Pointer to TVM emulator
Expand Down
1 change: 1 addition & 0 deletions emulator/emulator_export_list
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ _tvm_emulator_send_external_message
_tvm_emulator_send_internal_message
_tvm_emulator_destroy
_tvm_emulator_emulate_run_method
_tvm_emulator_emulate_run_method_detailed
_emulator_version