From dd5540d69e25f08a1c63760d3afb033208d9c99b Mon Sep 17 00:00:00 2001 From: Oleg Baranov Date: Tue, 19 Mar 2024 16:26:02 +0400 Subject: [PATCH] Single call optimized runGetMethod emulator (#920) * TVM Emulator optimized output method * TVM Emulator single call version * Fixed tvm_emulator export, changed to tvm_emulator_emulate * Removed imports * Set C7 from outside * Removed tvm_emulator_run_get_method_optimized * Renamed tvm_emulator_emulate to tvm_emulator_emulate_run_method --- emulator/emulator-extern.cpp | 60 +++++++++++++++++++++++++++++++++++ emulator/emulator-extern.h | 10 ++++++ emulator/emulator_export_list | 1 + emulator/tvm-emulator.hpp | 4 +++ 4 files changed, 75 insertions(+) diff --git a/emulator/emulator-extern.cpp b/emulator/emulator-extern.cpp index f8e2f7241..6d38ae59b 100644 --- a/emulator/emulator-extern.cpp +++ b/emulator/emulator-extern.cpp @@ -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 stack; + if (!vm::Stack::deserialize_to(stack_cs, stack)) { + return nullptr; + } + + td::Ref 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()) { diff --git a/emulator/emulator-extern.h b/emulator/emulator-extern.h index ce920f986..b418e5b0d 100644 --- a/emulator/emulator-extern.h +++ b/emulator/emulator-extern.h @@ -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 diff --git a/emulator/emulator_export_list b/emulator/emulator_export_list index e70166e74..93f5dbac8 100644 --- a/emulator/emulator_export_list +++ b/emulator/emulator_export_list @@ -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 diff --git a/emulator/tvm-emulator.hpp b/emulator/tvm-emulator.hpp index dafa2a5fc..a9f248b72 100644 --- a/emulator/tvm-emulator.hpp +++ b/emulator/tvm-emulator.hpp @@ -33,6 +33,10 @@ class TvmEmulator { } } + void set_c7_raw(td::Ref c7) { + args_.set_c7(std::move(c7)); + } + void set_prev_blocks_info(td::Ref tuple) { args_.set_prev_blocks_info(std::move(tuple)); }