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

Merge master #937

Merged
merged 8 commits into from
Mar 20, 2024
60 changes: 60 additions & 0 deletions emulator/emulator-extern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,66 @@ 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) {
auto params_cell = vm::std_boc_deserialize(td::Slice(params_boc, len));
if (params_cell.is_error()) {
return nullptr;
}
auto params_cs = vm::load_cell_slice(params_cell.move_as_ok());
auto code = params_cs.fetch_ref();
auto data = params_cs.fetch_ref();

auto stack_cs = vm::load_cell_slice(params_cs.fetch_ref());
auto params = vm::load_cell_slice(params_cs.fetch_ref());
auto c7_cs = vm::load_cell_slice(params.fetch_ref());
auto libs = vm::Dictionary(params.fetch_ref(), 256);

auto method_id = params_cs.fetch_long(32);

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

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

auto emulator = new emulator::TvmEmulator(code, data);
emulator->set_vm_verbosity_level(0);
emulator->set_gas_limit(gas_limit);
emulator->set_c7_raw(c7->fetch(0).as_tuple());
if (libs.is_empty()) {
emulator->set_libraries(std::move(libs));
}
auto result = emulator->run_get_method(int(method_id), stack);
delete emulator;

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

vm::CellBuilder cb;
cb.store_long(result.code, 32);
cb.store_long(result.gas_used, 64);
cb.store_ref(stack_cb.finalize());

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

auto sz = uint32_t(sok.size());
char* rn = (char*)malloc(sz + 4);
memcpy(rn, &sz, 4);
memcpy(rn+4, sok.data(), sz);

return rn;
}

const char *tvm_emulator_send_external_message(void *tvm_emulator, const char *message_body_boc) {
auto message_body_cell = boc_b64_to_cell(message_body_boc);
if (message_body_cell.is_error()) {
Expand Down
10 changes: 10 additions & 0 deletions emulator/emulator-extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ EMULATOR_EXPORT bool tvm_emulator_set_debug_enabled(void *tvm_emulator, bool deb
*/
EMULATOR_EXPORT const char *tvm_emulator_run_get_method(void *tvm_emulator, int method_id, const char *stack_boc);

/**
* @brief Optimized version of "run get method" with all passed parameters in a single call
* @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 Char* with first 4 bytes defining length, and the rest BoC serialized result
* Scheme: result$_ exit_code:(## 32) gas_used:(## 32) stack:^VmStack
*/
EMULATOR_EXPORT const char *tvm_emulator_emulate_run_method(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 @@ -21,3 +21,4 @@ _tvm_emulator_run_get_method
_tvm_emulator_send_external_message
_tvm_emulator_send_internal_message
_tvm_emulator_destroy
_tvm_emulator_emulate_run_method
4 changes: 4 additions & 0 deletions emulator/tvm-emulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class TvmEmulator {
}
}

void set_c7_raw(td::Ref<vm::Tuple> c7) {
args_.set_c7(std::move(c7));
}

void set_prev_blocks_info(td::Ref<vm::Tuple> tuple) {
args_.set_prev_blocks_info(std::move(tuple));
}
Expand Down
Loading