From 1b4d1a77eef92107e9c425bbbde1950bb52af11f Mon Sep 17 00:00:00 2001 From: altox Date: Sun, 28 Nov 2021 21:36:32 +0300 Subject: [PATCH 01/12] feature(crypto): vm-exec tool to run smart contracts locally --- crypto/CMakeLists.txt | 7 + crypto/vm-exec/vm-exec.cpp | 257 +++++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 crypto/vm-exec/vm-exec.cpp diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 79406ffca..35fc646e2 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -307,6 +307,13 @@ if (WINGETOPT_FOUND) target_link_libraries_system(tlbc wingetopt) endif() +add_executable(vm-exec vm-exec/vm-exec.cpp) +target_include_directories(vm-exec PUBLIC $) +target_link_libraries(vm-exec PUBLIC ton_crypto tdutils fift-lib terminal) +if (WINGETOPT_FOUND) + target_link_libraries_system(func wingetop ton_crypto tdutils ton_crypto fift-lib) +endif() + add_library(pow-miner-lib util/Miner.cpp util/Miner.h) target_include_directories(pow-miner-lib PUBLIC $) target_link_libraries(pow-miner-lib PUBLIC ton_crypto ton_block) diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp new file mode 100644 index 000000000..9ca75a86f --- /dev/null +++ b/crypto/vm-exec/vm-exec.cpp @@ -0,0 +1,257 @@ +#include "vm/vm.h" +#include "vm/cp0.h" +#include "vm/boc.h" +#include "vm/stack.hpp" +#include "fift/utils.h" +#include "crypto/block/block.h" +#include "td/utils/base64.h" +#include "td/utils/ScopeGuard.h" +#include "terminal/terminal.h" +#include "auto/tl/lite_api.hpp" +#include "td/utils/Random.h" +#include "td/utils/Time.h" +#include "td/utils/filesystem.h" +#include "td/utils/JsonBuilder.h" +#include "td/utils/OptionParser.h" +#include + +using namespace std::literals::string_literals; + +td::Ref prepare_vm_c7() { + auto now = static_cast(td::Time::now()); + td::BitArray<256> rand_seed; + td::RefInt256 rand_seed_int{true}; + td::Random::secure_bytes(rand_seed.as_slice()); + if (!rand_seed_int.unique_write().import_bits(rand_seed.cbits(), 256, false)) { + return {}; + } + auto balance = block::CurrencyCollection{1000, {}}.as_vm_tuple(); + auto tuple = vm::make_tuple_ref( + td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea + td::make_refint(0), // actions:Integer + td::make_refint(0), // msgs_sent:Integer + td::make_refint(now), // unixtime:Integer + td::make_refint(now), // block_lt:Integer + td::make_refint(now), // trans_lt:Integer + std::move(rand_seed_int), // rand_seed:Integer + balance // balance_remaining:[Integer (Maybe Cell)] + // my_addr, // myself:MsgAddressInt + // vm::StackEntry() // global_config:(Maybe Cell) ] = SmartContractInfo; + ); + LOG(DEBUG) << "SmartContractInfo initialized with " << vm::StackEntry(tuple).to_string(); + return vm::make_tuple_ref(std::move(tuple)); +} + +vm::StackEntry json_to_stack_entry(td::JsonObject& obj) { + auto type = get_json_object_string_field(obj, "type").move_as_ok(); + + if (type == "int") { + auto data = get_json_object_string_field(obj, "value").move_as_ok(); + return vm::StackEntry(td::dec_string_to_int256(data)); + } + if (type == "cell") { + auto data = get_json_object_string_field(obj, "value").move_as_ok(); + auto data_bytes = td::base64_decode(data).move_as_ok(); + auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); + auto data_cell = boc->load_cell().move_as_ok(); + return vm::StackEntry(data_cell.data_cell); + } + if (type == "cell_slice") { + auto data = get_json_object_string_field(obj, "value").move_as_ok(); + auto data_bytes = td::base64_decode(data).move_as_ok(); + auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); + auto data_cell = boc->load_cell().move_as_ok(); + return vm::StackEntry(td::make_ref(vm::CellSlice(data_cell))); + } + if (type == "null") { + return vm::StackEntry(); + } + if (type == "tuple") { + auto data = td::get_json_object_field(obj, "value", td::JsonValue::Type::Array, false).move_as_ok(); + auto& data_arr = data.get_array(); + + std::vector tuple_components; + + for (auto& x : data_arr) { + tuple_components.push_back(json_to_stack_entry(x.get_object())); + } + + return vm::StackEntry(tuple_components); + } + + return vm::StackEntry(); +} + +td::Ref json_to_stack(td::JsonArray& array) { + auto stack = td::make_ref(); + + for (auto& x : array) { + auto& obj = x.get_object(); + auto entry = json_to_stack_entry(obj); + stack.write().push(entry); + } + + return stack; +} + +std::string stack_entry_to_json(vm::StackEntry se) { + auto out = td::TerminalIO::out(); + + if (se.is_int()) { + return R"({ "type": "int", "value": ")" + td::dec_string(se.as_int()) + R"("})"; + } + if (se.is_cell()) { + auto value = td::base64_encode(vm::std_boc_serialize(se.as_cell()).move_as_ok()); + return R"({ "type": "cell", "value": ")" + value + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_slice) { + vm::CellBuilder b; + b.append_cellslice(se.as_slice()); + auto value = td::base64_encode(vm::std_boc_serialize(b.finalize()).move_as_ok()); + // auto value = td::base64_encode(vm::std_boc_serialize(se.as_slice()->get_base_cell()).move_as_ok()); + return R"({ "type": "cell_slice", "value": ")" + value + R"("})"; + } + if (se.is_null()) { + return R"({ "type": "null" })"; + } + if (se.is_tuple()) { + std::string res = R"({ "type": "tuple", "value": [)"; + + auto tuple = se.as_tuple(); + + for (auto& x : *tuple) { + res.append(stack_entry_to_json(x)); + res.append(","); + } + res = res.substr(0, res.length() - 1); + res += "] }"; + + return res; + } + + // + // Non supported by TVM + // + if (se.type() == vm::StackEntry::Type::t_builder) { + return se.as_builder()->to_hex(); + } + if (se.type() == vm::StackEntry::Type::t_vmcont) { + return R"({ "type": "t_vmcont" })"; + } + if (se.type() == vm::StackEntry::Type::t_string) { + return R"({ "type": "string", value: ")" + se.as_string() + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_bytes) { + return R"({ "type": "bytes", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_bitstring) { + return R"({ "type": "bitstring", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; + } + + return R"({ "type": "unknown" })"; +} + +std::string stack2json(vm::Ref stack) { + if (stack->is_empty()) { + return "[]"; + } + std::string out = "["; + for (const auto& x : stack->as_span()) { + out.append(stack_entry_to_json(x)); + out.append(","); + } + out = out.substr(0, out.length() - 1); + out.append("]"); + return out; +} + +std::string run_vm(td::Ref code_cell, td::Ref data, td::JsonArray& stack_array, int function_selector) { + auto out = td::TerminalIO::out(); + auto code = code_cell; + + auto stack = json_to_stack(stack_array); + + td::int64 method_id = function_selector; + stack.write().push_smallint(method_id); + + long long gas_limit = vm::GasLimits::infty; + vm::GasLimits gas{gas_limit}; + LOG(DEBUG) << "creating VM"; + vm::VmState vm{code, std::move(stack), gas, 1, data, vm::VmLog()}; + vm.set_c7(prepare_vm_c7()); // tuple with SmartContractInfo + LOG(INFO) << "starting VM to run method `" << 0 << "` (" << 0 << ") of smart contract " << 0; + + int exit_code; + try { + exit_code = ~vm.run(); + } catch (vm::VmVirtError& err) { + LOG(ERROR) << "virtualization error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + } catch (vm::VmError& err) { + LOG(ERROR) << "error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + } + stack = vm.get_stack_ref(); + + std::string result; + + auto committed_state = vm.get_committed_state(); + + auto serialized_data_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c4).move_as_ok()); + auto serialized_action_list_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c5).move_as_ok()); + auto new_code_cell = td::base64_encode(vm::std_boc_serialize(vm.get_code()->get_base_cell()).move_as_ok()); + + result += "{"; + result += R"("exit_code":)" + std::to_string(exit_code) + ","; + result += R"("stack":)" + stack2json(stack) + ","; + result += R"("data_cell": ")" + serialized_data_cell + R"(",)"; + result += R"("action_list_cell": ")" + serialized_action_list_cell + R"(")"; + result += "}"; + + return result; +} + +void execute(td::Slice config_file_name) { + auto out = td::TerminalIO::out(); + + std::string input_file = config_file_name.str(); + auto input_data = td::read_file(input_file).move_as_ok().as_slice().str(); + + auto input_json = td::json_decode(input_data).move_as_ok(); + auto& obj = input_json.get_object(); + + auto code = td::get_json_object_string_field(obj, "code", false).move_as_ok(); + auto data = td::get_json_object_string_field(obj, "data", false).move_as_ok(); + auto function_selector = td::get_json_object_int_field(obj, "function_selector", false).move_as_ok(); + auto initial_stack = td::get_json_object_field(obj, "init_stack", td::JsonValue::Type::Array, false).move_as_ok(); + + auto& initial_stack_array = initial_stack.get_array(); + + auto decoded_code = td::base64_decode(code).move_as_ok(); + + auto data_bytes = td::base64_decode(data).move_as_ok(); + auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); + auto data_cell = boc->load_cell().move_as_ok(); + + auto code_s = td::Slice(decoded_code); + auto compiled_source = fift::compile_asm(code_s, "", false).move_as_ok(); + auto res = run_vm(compiled_source, data_cell.data_cell, initial_stack_array, function_selector); + out << res; +} + +int main(int argc, char* argv[]) { + SET_VERBOSITY_LEVEL(verbosity_FATAL); + + td::OptionParser p; + + p.set_description("TVM JSON Executor"); + p.add_option('h', "help", "prints_help", [&]() { + char b[10240]; + td::StringBuilder sb(td::MutableSlice{b, 10000}); + sb << p; + std::cout << sb.as_cslice().c_str(); + std::exit(2); + }); + p.add_option('c', "config", "path to config", [&](td::Slice fname) { execute(fname); }); + p.run(argc, argv).ensure(); + + return 0; +} From 3d9c8cece2e16f8d47159e4b4fea41a0b5c3be4d Mon Sep 17 00:00:00 2001 From: altox Date: Tue, 30 Nov 2021 00:02:44 +0300 Subject: [PATCH 02/12] wip(vm-exec): return gas_consumed & don't fail when vm thows exception --- CMakeLists.txt | 8 ++++++-- crypto/vm-exec/vm-exec.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a97a9c960..9cd36b771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) + +set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl/") +set(GSL_ROOT_DIR "/opt/homebrew/opt/gsl/") + project(TON VERSION 0.5 LANGUAGES C CXX) set(CMAKE_POSITION_INDEPENDENT_CODE ON) #set(OPENSSL_USE_STATIC_LIBS TRUE) @@ -80,7 +84,7 @@ else() endif() #BEGIN internal -option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." OFF) +option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." ON) if (TON_ONLY_TONLIB) set(NOT_TON_ONLY_TONLIB false) else() @@ -204,7 +208,7 @@ find_package(Threads REQUIRED) find_package(ZLIB REQUIRED) if (TON_ARCH AND NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TON_ARCH}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") endif() if (THREADS_HAVE_PTHREAD_ARG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index 9ca75a86f..cf7163b76 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -7,13 +7,11 @@ #include "td/utils/base64.h" #include "td/utils/ScopeGuard.h" #include "terminal/terminal.h" -#include "auto/tl/lite_api.hpp" #include "td/utils/Random.h" #include "td/utils/Time.h" #include "td/utils/filesystem.h" #include "td/utils/JsonBuilder.h" #include "td/utils/OptionParser.h" -#include using namespace std::literals::string_literals; @@ -95,8 +93,6 @@ td::Ref json_to_stack(td::JsonArray& array) { } std::string stack_entry_to_json(vm::StackEntry se) { - auto out = td::TerminalIO::out(); - if (se.is_int()) { return R"({ "type": "int", "value": ")" + td::dec_string(se.as_int()) + R"("})"; } @@ -166,7 +162,6 @@ std::string stack2json(vm::Ref stack) { } std::string run_vm(td::Ref code_cell, td::Ref data, td::JsonArray& stack_array, int function_selector) { - auto out = td::TerminalIO::out(); auto code = code_cell; auto stack = json_to_stack(stack_array); @@ -189,6 +184,11 @@ std::string run_vm(td::Ref code_cell, td::Ref data, td::Json } catch (vm::VmError& err) { LOG(ERROR) << "error while running VM to locally compute runSmcMethod result: " << err.get_msg(); } + + if (exit_code != 0) { + return R"({ "exit_code": )" + std::to_string(exit_code) + "}"; + } + stack = vm.get_stack_ref(); std::string result; @@ -197,12 +197,12 @@ std::string run_vm(td::Ref code_cell, td::Ref data, td::Json auto serialized_data_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c4).move_as_ok()); auto serialized_action_list_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c5).move_as_ok()); - auto new_code_cell = td::base64_encode(vm::std_boc_serialize(vm.get_code()->get_base_cell()).move_as_ok()); result += "{"; result += R"("exit_code":)" + std::to_string(exit_code) + ","; result += R"("stack":)" + stack2json(stack) + ","; result += R"("data_cell": ")" + serialized_data_cell + R"(",)"; + result += R"("gas_consumed": ")" + vm.gas_consumed() + R"(",)"; result += R"("action_list_cell": ")" + serialized_action_list_cell + R"(")"; result += "}"; From 11a8ce7d88b28c2f9d9f51d1ff2359f941bd64cc Mon Sep 17 00:00:00 2001 From: altox Date: Wed, 1 Dec 2021 01:46:23 +0300 Subject: [PATCH 03/12] wip(vm-exec): revert cmake --- CMakeLists.txt | 211 ++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 108 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd36b771..486b2f57f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,5 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) - -set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl/") -set(GSL_ROOT_DIR "/opt/homebrew/opt/gsl/") - project(TON VERSION 0.5 LANGUAGES C CXX) set(CMAKE_POSITION_INDEPENDENT_CODE ON) #set(OPENSSL_USE_STATIC_LIBS TRUE) @@ -84,7 +80,7 @@ else() endif() #BEGIN internal -option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." ON) +option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." OFF) if (TON_ONLY_TONLIB) set(NOT_TON_ONLY_TONLIB false) else() @@ -208,7 +204,7 @@ find_package(Threads REQUIRED) find_package(ZLIB REQUIRED) if (TON_ARCH AND NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TON_ARCH}") endif() if (THREADS_HAVE_PTHREAD_ARG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") @@ -272,14 +268,14 @@ endif() set(INTERNAL_COMPILE "0") #BEGIN internal - add_definitions(-D_INTERNAL_COMPILE=1) - set(INTERNAL_COMPILE "1") +add_definitions(-D_INTERNAL_COMPILE=1) +set(INTERNAL_COMPILE "1") #END internal set(TONLIB_COMPILE "0") #BEGIN tonlib - add_definitions(-D_TONLIB_COMPILE=1) - set(TONLIB_COMPILE "1") +add_definitions(-D_TONLIB_COMPILE=1) +set(TONLIB_COMPILE "1") #END tonlib include(AddCXXCompilerFlag) @@ -387,26 +383,26 @@ add_subdirectory(tonlib) #BEGIN internal if (NOT TON_ONLY_TONLIB) -add_subdirectory(common) -add_subdirectory(tdfec) -add_subdirectory(keyring) -add_subdirectory(fec) -add_subdirectory(rldp) -add_subdirectory(rldp2) -add_subdirectory(dht) -add_subdirectory(overlay) -add_subdirectory(catchain) -add_subdirectory(validator-session) -add_subdirectory(validator) -add_subdirectory(blockchain-explorer) -add_subdirectory(storage) -add_subdirectory(validator-engine) -add_subdirectory(validator-engine-console) -add_subdirectory(create-hardfork) -add_subdirectory(dht-server) -add_subdirectory(utils) -add_subdirectory(http) -add_subdirectory(rldp-http-proxy) + add_subdirectory(common) + add_subdirectory(tdfec) + add_subdirectory(keyring) + add_subdirectory(fec) + add_subdirectory(rldp) + add_subdirectory(rldp2) + add_subdirectory(dht) + add_subdirectory(overlay) + add_subdirectory(catchain) + add_subdirectory(validator-session) + add_subdirectory(validator) + add_subdirectory(blockchain-explorer) + add_subdirectory(storage) + add_subdirectory(validator-engine) + add_subdirectory(validator-engine-console) + add_subdirectory(create-hardfork) + add_subdirectory(dht-server) + add_subdirectory(utils) + add_subdirectory(http) + add_subdirectory(rldp-http-proxy) endif() #END internal @@ -460,78 +456,78 @@ endif() #BEGIN internal if (NOT TON_ONLY_TONLIB) -add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE}) -target_link_libraries(test-db PRIVATE ton_db memprof tdfec) + add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE}) + target_link_libraries(test-db PRIVATE ton_db memprof tdfec) -add_executable(test-storage test/test-td-main.cpp ${STORAGE_TEST_SOURCE}) -target_link_libraries(test-storage PRIVATE storage ton_db memprof tl_api tl-utils fec rldp2) + add_executable(test-storage test/test-td-main.cpp ${STORAGE_TEST_SOURCE}) + target_link_libraries(test-storage PRIVATE storage ton_db memprof tl_api tl-utils fec rldp2) -add_executable(test-rocksdb test/test-rocksdb.cpp) -target_link_libraries(test-rocksdb PRIVATE memprof tddb tdutils) + add_executable(test-rocksdb test/test-rocksdb.cpp) + target_link_libraries(test-rocksdb PRIVATE memprof tddb tdutils) -add_executable(test-tddb test/test-td-main.cpp ${TDDB_TEST_SOURCE}) -target_link_libraries(test-tddb PRIVATE tdutils tddb ${CMAKE_THREAD_LIBS_INIT} memprof) + add_executable(test-tddb test/test-td-main.cpp ${TDDB_TEST_SOURCE}) + target_link_libraries(test-tddb PRIVATE tdutils tddb ${CMAKE_THREAD_LIBS_INIT} memprof) -add_executable(test-fec test/test-td-main.cpp ${FEC_TEST_SOURCE}) -target_link_libraries(test-fec PRIVATE tdfec tdutils ${CMAKE_THREAD_LIBS_INIT}) -if (USE_LIBRAPTORQ) - target_link_libraries(test-fec PRIVATE third_party_fec) - target_compile_definitions(test-fec PRIVATE "USE_LIBRAPTORQ=1") -endif() - -add_executable(test-hello-world test/test-hello-world.cpp ) -target_link_libraries(test-hello-world tl_api ton_crypto) - -add_executable(test-adnl test/test-adnl.cpp) -target_link_libraries(test-adnl adnl adnltest dht tl_api) -add_executable(test-dht test/test-dht.cpp) -target_link_libraries(test-dht adnl adnltest dht tl_api) -add_executable(test-rldp test/test-rldp.cpp) -target_link_libraries(test-rldp adnl adnltest dht rldp tl_api) -add_executable(test-rldp2 test/test-rldp2.cpp) -target_link_libraries(test-rldp2 adnl adnltest dht rldp2 tl_api) -add_executable(test-validator-session-state test/test-validator-session-state.cpp) -target_link_libraries(test-validator-session-state adnl dht rldp validatorsession tl_api) - -#add_executable(test-node test/test-node.cpp) -#target_link_libraries(test-node overlay tdutils tdactor adnl tl_api dht -# catchain validatorsession) - -add_executable(test-catchain test/test-catchain.cpp) -target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp tl_api dht - catchain ) -#add_executable(test-validator-session test/test-validator-session.cpp) -#target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht -# catchain validatorsession) -add_executable(test-ton-collator test/test-ton-collator.cpp) -target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht - catchain validatorsession validator-disk ton_validator validator-disk ) -#add_executable(test-validator test/test-validator.cpp) -#target_link_libraries(test-validator overlay tdutils tdactor adnl tl_api dht -# rldp catchain validatorsession ton-node validator ton_validator validator memprof ${JEMALLOC_LIBRARIES}) -#add_executable(test-ext-server test/test-ext-server.cpp) -#target_link_libraries(test-ext-server tdutils tdactor adnl tl_api dht ) -#add_executable(test-ext-client test/test-ext-client.cpp) -#target_link_libraries(test-ext-client tdutils tdactor adnl tl_api tl-lite-utils) - -add_executable(test-http test/test-http.cpp) -target_link_libraries(test-http PRIVATE tonhttp) - -get_directory_property(HAS_PARENT PARENT_DIRECTORY) -if (HAS_PARENT) - set(ALL_TEST_SOURCE - ${TDUTILS_TEST_SOURCE} - ${TDACTOR_TEST_SOURCE} - ${NET_TEST_SOURCE} - ${TDDB_TEST_SOURCE} - ${FEC_TEST_SOURCE} - ${ED25519_TEST_SOURCE} - ${TONDB_TEST_SOURCE} - ${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE} - PARENT_SCOPE) -endif() -add_library(all_tests INTERFACE) -target_link_libraries(all_tests INTERFACE tdutils tdactor tdnet tdfec ton_db ton_crypto fift-lib) + add_executable(test-fec test/test-td-main.cpp ${FEC_TEST_SOURCE}) + target_link_libraries(test-fec PRIVATE tdfec tdutils ${CMAKE_THREAD_LIBS_INIT}) + if (USE_LIBRAPTORQ) + target_link_libraries(test-fec PRIVATE third_party_fec) + target_compile_definitions(test-fec PRIVATE "USE_LIBRAPTORQ=1") + endif() + + add_executable(test-hello-world test/test-hello-world.cpp ) + target_link_libraries(test-hello-world tl_api ton_crypto) + + add_executable(test-adnl test/test-adnl.cpp) + target_link_libraries(test-adnl adnl adnltest dht tl_api) + add_executable(test-dht test/test-dht.cpp) + target_link_libraries(test-dht adnl adnltest dht tl_api) + add_executable(test-rldp test/test-rldp.cpp) + target_link_libraries(test-rldp adnl adnltest dht rldp tl_api) + add_executable(test-rldp2 test/test-rldp2.cpp) + target_link_libraries(test-rldp2 adnl adnltest dht rldp2 tl_api) + add_executable(test-validator-session-state test/test-validator-session-state.cpp) + target_link_libraries(test-validator-session-state adnl dht rldp validatorsession tl_api) + + #add_executable(test-node test/test-node.cpp) + #target_link_libraries(test-node overlay tdutils tdactor adnl tl_api dht + # catchain validatorsession) + + add_executable(test-catchain test/test-catchain.cpp) + target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp tl_api dht + catchain ) + #add_executable(test-validator-session test/test-validator-session.cpp) + #target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht + # catchain validatorsession) + add_executable(test-ton-collator test/test-ton-collator.cpp) + target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht + catchain validatorsession validator-disk ton_validator validator-disk ) + #add_executable(test-validator test/test-validator.cpp) + #target_link_libraries(test-validator overlay tdutils tdactor adnl tl_api dht + # rldp catchain validatorsession ton-node validator ton_validator validator memprof ${JEMALLOC_LIBRARIES}) + #add_executable(test-ext-server test/test-ext-server.cpp) + #target_link_libraries(test-ext-server tdutils tdactor adnl tl_api dht ) + #add_executable(test-ext-client test/test-ext-client.cpp) + #target_link_libraries(test-ext-client tdutils tdactor adnl tl_api tl-lite-utils) + + add_executable(test-http test/test-http.cpp) + target_link_libraries(test-http PRIVATE tonhttp) + + get_directory_property(HAS_PARENT PARENT_DIRECTORY) + if (HAS_PARENT) + set(ALL_TEST_SOURCE + ${TDUTILS_TEST_SOURCE} + ${TDACTOR_TEST_SOURCE} + ${NET_TEST_SOURCE} + ${TDDB_TEST_SOURCE} + ${FEC_TEST_SOURCE} + ${ED25519_TEST_SOURCE} + ${TONDB_TEST_SOURCE} + ${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE} + PARENT_SCOPE) + endif() + add_library(all_tests INTERFACE) + target_link_libraries(all_tests INTERFACE tdutils tdactor tdnet tdfec ton_db ton_crypto fift-lib) endif() #END internal @@ -554,16 +550,15 @@ add_test(test-tonlib-offline test-tonlib-offline) #BEGIN internal if (NOT TON_ONLY_TONLIB) -add_test(test-adnl test-adnl) -add_test(test-dht test-dht) -add_test(test-rldp test-rldp) -add_test(test-rldp2 test-rldp2) -#add_test(test-validator-session-state test-validator-session-state) -add_test(test-catchain test-catchain) + add_test(test-adnl test-adnl) + add_test(test-dht test-dht) + add_test(test-rldp test-rldp) + add_test(test-rldp2 test-rldp2) + #add_test(test-validator-session-state test-validator-session-state) + add_test(test-catchain test-catchain) -add_test(test-fec test-fec) -add_test(test-tddb test-tddb ${TEST_OPTIONS}) -add_test(test-db test-db ${TEST_OPTIONS}) + add_test(test-fec test-fec) + add_test(test-tddb test-tddb ${TEST_OPTIONS}) + add_test(test-db test-db ${TEST_OPTIONS}) endif() #END internal - From 2ad439c31b5cf50d267a96346862c8cc22f3e7c9 Mon Sep 17 00:00:00 2001 From: altox Date: Wed, 1 Dec 2021 01:54:16 +0300 Subject: [PATCH 04/12] wip(vm-exec): fix gas_consumed field serialization --- crypto/vm-exec/vm-exec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index cf7163b76..aea23a7a3 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -202,7 +202,7 @@ std::string run_vm(td::Ref code_cell, td::Ref data, td::Json result += R"("exit_code":)" + std::to_string(exit_code) + ","; result += R"("stack":)" + stack2json(stack) + ","; result += R"("data_cell": ")" + serialized_data_cell + R"(",)"; - result += R"("gas_consumed": ")" + vm.gas_consumed() + R"(",)"; + result += R"("gas_consumed": )" + std::to_string(vm.gas_consumed()) + R"(,)"; result += R"("action_list_cell": ")" + serialized_action_list_cell + R"(")"; result += "}"; From f4092a0b664570ad4700e44c405061087fbabeaf Mon Sep 17 00:00:00 2001 From: altox Date: Tue, 28 Dec 2021 21:29:55 +0300 Subject: [PATCH 05/12] wip(vm-exec): switch to running contract not from source but from compiled boc --- crypto/vm-exec/vm-exec.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index aea23a7a3..df717843c 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -164,6 +164,8 @@ std::string stack2json(vm::Ref stack) { std::string run_vm(td::Ref code_cell, td::Ref data, td::JsonArray& stack_array, int function_selector) { auto code = code_cell; + vm::init_op_cp0(); + auto stack = json_to_stack(stack_array); td::int64 method_id = function_selector; @@ -225,15 +227,15 @@ void execute(td::Slice config_file_name) { auto& initial_stack_array = initial_stack.get_array(); - auto decoded_code = td::base64_decode(code).move_as_ok(); - auto data_bytes = td::base64_decode(data).move_as_ok(); auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); auto data_cell = boc->load_cell().move_as_ok(); - auto code_s = td::Slice(decoded_code); - auto compiled_source = fift::compile_asm(code_s, "", false).move_as_ok(); - auto res = run_vm(compiled_source, data_cell.data_cell, initial_stack_array, function_selector); + auto decoded_code = td::base64_decode(code).move_as_ok(); + auto code_boc = vm::std_boc_deserialize(decoded_code).move_as_ok(); + auto code_cell = code_boc->load_cell().move_as_ok(); + + auto res = run_vm(code_cell.data_cell, data_cell.data_cell, initial_stack_array, function_selector); out << res; } From f4ee096e4376d3d08c673de2408cfc218e3c3710 Mon Sep 17 00:00:00 2001 From: altox Date: Mon, 14 Mar 2022 17:42:15 +0300 Subject: [PATCH 06/12] more work on vm-exec --- CMakeLists.txt | 231 ++++++++++--------- crypto/CMakeLists.txt | 36 ++- crypto/vm-exec/StringLog.h | 39 ++++ crypto/vm-exec/common.cpp | 247 +++++++++++++++++++++ crypto/vm-exec/common.h | 39 ++++ crypto/vm-exec/vm-exec-lib.cpp | 37 ++++ crypto/vm-exec/vm-exec-lib_export_list | 1 + crypto/vm-exec/vm-exec.cpp | 293 +++++-------------------- crypto/wallet_gen/wallet_gen.cpp | 30 +++ tdutils/td/utils/port/config.h | 7 + tonlib/CMakeLists.txt | 10 +- 11 files changed, 621 insertions(+), 349 deletions(-) create mode 100644 crypto/vm-exec/StringLog.h create mode 100644 crypto/vm-exec/common.cpp create mode 100644 crypto/vm-exec/common.h create mode 100644 crypto/vm-exec/vm-exec-lib.cpp create mode 100644 crypto/vm-exec/vm-exec-lib_export_list create mode 100644 crypto/wallet_gen/wallet_gen.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 486b2f57f..2e389230f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,25 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) + +#set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl/") +#set(GSL_ROOT_DIR "/opt/homebrew/opt/gsl/") +if(EMSCRIPTEN) + set(OPENSSL_FOUND "1") + set(OPENSSL_ROOT_DIR "/Users/altox/Desktop/openssl/openssl-1.1.1d/") + set(OPENSSL_INCLUDE_DIR "/Users/altox/Desktop/openssl/openssl-1.1.1d/include/") + set(OPENSSL_CRYPTO_LIBRARY "/Users/altox/Desktop/openssl/openssl-1.1.1d/libcrypto.a") + set(OPENSSL_SSL_LIBRARY "/Users/altox/Desktop/openssl/openssl-1.1.1d/libssl.a") + set(OPENSSL_LIBRARIES "${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}") + + set(ZLIB_LIBRARY /Users/altox/Desktop/zlib/) + set(ZLIB_INCLUDE_DIR /Users/altox/Desktop/zlib/) +else() + set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl/") + set(GSL_ROOT_DIR "/opt/homebrew/opt/gsl/") +endif() + + + project(TON VERSION 0.5 LANGUAGES C CXX) set(CMAKE_POSITION_INDEPENDENT_CODE ON) #set(OPENSSL_USE_STATIC_LIBS TRUE) @@ -80,7 +100,7 @@ else() endif() #BEGIN internal -option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." OFF) +option(TON_ONLY_TONLIB "Use \"ON\" to build only tonlib." ON) if (TON_ONLY_TONLIB) set(NOT_TON_ONLY_TONLIB false) else() @@ -204,7 +224,7 @@ find_package(Threads REQUIRED) find_package(ZLIB REQUIRED) if (TON_ARCH AND NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=${TON_ARCH}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") endif() if (THREADS_HAVE_PTHREAD_ARG) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") @@ -245,10 +265,10 @@ elseif (CLANG OR GCC) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} -fvisibility=hidden -Wl,-dead_strip,-x,-S") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,--exclude-libs,ALL") +# set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,--exclude-libs,ALL") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") if (NOT TON_USE_ASAN AND NOT TON_USE_TSAN AND NOT MEMPROF) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--exclude-libs,ALL") +# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--exclude-libs,ALL") endif() endif() elseif (INTEL) @@ -268,14 +288,14 @@ endif() set(INTERNAL_COMPILE "0") #BEGIN internal -add_definitions(-D_INTERNAL_COMPILE=1) -set(INTERNAL_COMPILE "1") + add_definitions(-D_INTERNAL_COMPILE=1) + set(INTERNAL_COMPILE "1") #END internal set(TONLIB_COMPILE "0") #BEGIN tonlib -add_definitions(-D_TONLIB_COMPILE=1) -set(TONLIB_COMPILE "1") + add_definitions(-D_TONLIB_COMPILE=1) + set(TONLIB_COMPILE "1") #END tonlib include(AddCXXCompilerFlag) @@ -383,26 +403,26 @@ add_subdirectory(tonlib) #BEGIN internal if (NOT TON_ONLY_TONLIB) - add_subdirectory(common) - add_subdirectory(tdfec) - add_subdirectory(keyring) - add_subdirectory(fec) - add_subdirectory(rldp) - add_subdirectory(rldp2) - add_subdirectory(dht) - add_subdirectory(overlay) - add_subdirectory(catchain) - add_subdirectory(validator-session) - add_subdirectory(validator) - add_subdirectory(blockchain-explorer) - add_subdirectory(storage) - add_subdirectory(validator-engine) - add_subdirectory(validator-engine-console) - add_subdirectory(create-hardfork) - add_subdirectory(dht-server) - add_subdirectory(utils) - add_subdirectory(http) - add_subdirectory(rldp-http-proxy) +add_subdirectory(common) +add_subdirectory(tdfec) +add_subdirectory(keyring) +add_subdirectory(fec) +add_subdirectory(rldp) +add_subdirectory(rldp2) +add_subdirectory(dht) +add_subdirectory(overlay) +add_subdirectory(catchain) +add_subdirectory(validator-session) +add_subdirectory(validator) +add_subdirectory(blockchain-explorer) +add_subdirectory(storage) +add_subdirectory(validator-engine) +add_subdirectory(validator-engine-console) +add_subdirectory(create-hardfork) +add_subdirectory(dht-server) +add_subdirectory(utils) +add_subdirectory(http) +add_subdirectory(rldp-http-proxy) endif() #END internal @@ -456,78 +476,78 @@ endif() #BEGIN internal if (NOT TON_ONLY_TONLIB) - add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE}) - target_link_libraries(test-db PRIVATE ton_db memprof tdfec) +add_executable(test-db test/test-td-main.cpp ${TONDB_TEST_SOURCE}) +target_link_libraries(test-db PRIVATE ton_db memprof tdfec) - add_executable(test-storage test/test-td-main.cpp ${STORAGE_TEST_SOURCE}) - target_link_libraries(test-storage PRIVATE storage ton_db memprof tl_api tl-utils fec rldp2) +add_executable(test-storage test/test-td-main.cpp ${STORAGE_TEST_SOURCE}) +target_link_libraries(test-storage PRIVATE storage ton_db memprof tl_api tl-utils fec rldp2) - add_executable(test-rocksdb test/test-rocksdb.cpp) - target_link_libraries(test-rocksdb PRIVATE memprof tddb tdutils) +add_executable(test-rocksdb test/test-rocksdb.cpp) +target_link_libraries(test-rocksdb PRIVATE memprof tddb tdutils) - add_executable(test-tddb test/test-td-main.cpp ${TDDB_TEST_SOURCE}) - target_link_libraries(test-tddb PRIVATE tdutils tddb ${CMAKE_THREAD_LIBS_INIT} memprof) +add_executable(test-tddb test/test-td-main.cpp ${TDDB_TEST_SOURCE}) +target_link_libraries(test-tddb PRIVATE tdutils tddb ${CMAKE_THREAD_LIBS_INIT} memprof) - add_executable(test-fec test/test-td-main.cpp ${FEC_TEST_SOURCE}) - target_link_libraries(test-fec PRIVATE tdfec tdutils ${CMAKE_THREAD_LIBS_INIT}) - if (USE_LIBRAPTORQ) - target_link_libraries(test-fec PRIVATE third_party_fec) - target_compile_definitions(test-fec PRIVATE "USE_LIBRAPTORQ=1") - endif() - - add_executable(test-hello-world test/test-hello-world.cpp ) - target_link_libraries(test-hello-world tl_api ton_crypto) - - add_executable(test-adnl test/test-adnl.cpp) - target_link_libraries(test-adnl adnl adnltest dht tl_api) - add_executable(test-dht test/test-dht.cpp) - target_link_libraries(test-dht adnl adnltest dht tl_api) - add_executable(test-rldp test/test-rldp.cpp) - target_link_libraries(test-rldp adnl adnltest dht rldp tl_api) - add_executable(test-rldp2 test/test-rldp2.cpp) - target_link_libraries(test-rldp2 adnl adnltest dht rldp2 tl_api) - add_executable(test-validator-session-state test/test-validator-session-state.cpp) - target_link_libraries(test-validator-session-state adnl dht rldp validatorsession tl_api) - - #add_executable(test-node test/test-node.cpp) - #target_link_libraries(test-node overlay tdutils tdactor adnl tl_api dht - # catchain validatorsession) - - add_executable(test-catchain test/test-catchain.cpp) - target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp tl_api dht - catchain ) - #add_executable(test-validator-session test/test-validator-session.cpp) - #target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht - # catchain validatorsession) - add_executable(test-ton-collator test/test-ton-collator.cpp) - target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht - catchain validatorsession validator-disk ton_validator validator-disk ) - #add_executable(test-validator test/test-validator.cpp) - #target_link_libraries(test-validator overlay tdutils tdactor adnl tl_api dht - # rldp catchain validatorsession ton-node validator ton_validator validator memprof ${JEMALLOC_LIBRARIES}) - #add_executable(test-ext-server test/test-ext-server.cpp) - #target_link_libraries(test-ext-server tdutils tdactor adnl tl_api dht ) - #add_executable(test-ext-client test/test-ext-client.cpp) - #target_link_libraries(test-ext-client tdutils tdactor adnl tl_api tl-lite-utils) - - add_executable(test-http test/test-http.cpp) - target_link_libraries(test-http PRIVATE tonhttp) - - get_directory_property(HAS_PARENT PARENT_DIRECTORY) - if (HAS_PARENT) - set(ALL_TEST_SOURCE - ${TDUTILS_TEST_SOURCE} - ${TDACTOR_TEST_SOURCE} - ${NET_TEST_SOURCE} - ${TDDB_TEST_SOURCE} - ${FEC_TEST_SOURCE} - ${ED25519_TEST_SOURCE} - ${TONDB_TEST_SOURCE} - ${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE} - PARENT_SCOPE) - endif() - add_library(all_tests INTERFACE) - target_link_libraries(all_tests INTERFACE tdutils tdactor tdnet tdfec ton_db ton_crypto fift-lib) +add_executable(test-fec test/test-td-main.cpp ${FEC_TEST_SOURCE}) +target_link_libraries(test-fec PRIVATE tdfec tdutils ${CMAKE_THREAD_LIBS_INIT}) +if (USE_LIBRAPTORQ) + target_link_libraries(test-fec PRIVATE third_party_fec) + target_compile_definitions(test-fec PRIVATE "USE_LIBRAPTORQ=1") +endif() + +add_executable(test-hello-world test/test-hello-world.cpp ) +target_link_libraries(test-hello-world tl_api ton_crypto) + +add_executable(test-adnl test/test-adnl.cpp) +target_link_libraries(test-adnl adnl adnltest dht tl_api) +add_executable(test-dht test/test-dht.cpp) +target_link_libraries(test-dht adnl adnltest dht tl_api) +add_executable(test-rldp test/test-rldp.cpp) +target_link_libraries(test-rldp adnl adnltest dht rldp tl_api) +add_executable(test-rldp2 test/test-rldp2.cpp) +target_link_libraries(test-rldp2 adnl adnltest dht rldp2 tl_api) +add_executable(test-validator-session-state test/test-validator-session-state.cpp) +target_link_libraries(test-validator-session-state adnl dht rldp validatorsession tl_api) + +#add_executable(test-node test/test-node.cpp) +#target_link_libraries(test-node overlay tdutils tdactor adnl tl_api dht +# catchain validatorsession) + +add_executable(test-catchain test/test-catchain.cpp) +target_link_libraries(test-catchain overlay tdutils tdactor adnl adnltest rldp tl_api dht + catchain ) +#add_executable(test-validator-session test/test-validator-session.cpp) +#target_link_libraries(test-validator-session overlay tdutils tdactor adnl tl_api dht +# catchain validatorsession) +add_executable(test-ton-collator test/test-ton-collator.cpp) +target_link_libraries(test-ton-collator overlay tdutils tdactor adnl tl_api dht + catchain validatorsession validator-disk ton_validator validator-disk ) +#add_executable(test-validator test/test-validator.cpp) +#target_link_libraries(test-validator overlay tdutils tdactor adnl tl_api dht +# rldp catchain validatorsession ton-node validator ton_validator validator memprof ${JEMALLOC_LIBRARIES}) +#add_executable(test-ext-server test/test-ext-server.cpp) +#target_link_libraries(test-ext-server tdutils tdactor adnl tl_api dht ) +#add_executable(test-ext-client test/test-ext-client.cpp) +#target_link_libraries(test-ext-client tdutils tdactor adnl tl_api tl-lite-utils) + +add_executable(test-http test/test-http.cpp) +target_link_libraries(test-http PRIVATE tonhttp) + +get_directory_property(HAS_PARENT PARENT_DIRECTORY) +if (HAS_PARENT) + set(ALL_TEST_SOURCE + ${TDUTILS_TEST_SOURCE} + ${TDACTOR_TEST_SOURCE} + ${NET_TEST_SOURCE} + ${TDDB_TEST_SOURCE} + ${FEC_TEST_SOURCE} + ${ED25519_TEST_SOURCE} + ${TONDB_TEST_SOURCE} + ${CELLS_TEST_SOURCE} # ${TONVM_TEST_SOURCE} ${FIFT_TEST_SOURCE} ${TONLIB_ONLINE_TEST_SOURCE} + PARENT_SCOPE) +endif() +add_library(all_tests INTERFACE) +target_link_libraries(all_tests INTERFACE tdutils tdactor tdnet tdfec ton_db ton_crypto fift-lib) endif() #END internal @@ -550,15 +570,16 @@ add_test(test-tonlib-offline test-tonlib-offline) #BEGIN internal if (NOT TON_ONLY_TONLIB) - add_test(test-adnl test-adnl) - add_test(test-dht test-dht) - add_test(test-rldp test-rldp) - add_test(test-rldp2 test-rldp2) - #add_test(test-validator-session-state test-validator-session-state) - add_test(test-catchain test-catchain) +add_test(test-adnl test-adnl) +add_test(test-dht test-dht) +add_test(test-rldp test-rldp) +add_test(test-rldp2 test-rldp2) +#add_test(test-validator-session-state test-validator-session-state) +add_test(test-catchain test-catchain) - add_test(test-fec test-fec) - add_test(test-tddb test-tddb ${TEST_OPTIONS}) - add_test(test-db test-db ${TEST_OPTIONS}) +add_test(test-fec test-fec) +add_test(test-tddb test-tddb ${TEST_OPTIONS}) +add_test(test-db test-db ${TEST_OPTIONS}) endif() #END internal + diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 35fc646e2..ac1a18c27 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -307,9 +307,39 @@ if (WINGETOPT_FOUND) target_link_libraries_system(tlbc wingetopt) endif() -add_executable(vm-exec vm-exec/vm-exec.cpp) +add_executable(vm-exec vm-exec/vm-exec.cpp vm-exec/StringLog.h vm-exec/common.cpp vm-exec/common.h) target_include_directories(vm-exec PUBLIC $) -target_link_libraries(vm-exec PUBLIC ton_crypto tdutils fift-lib terminal) +target_link_libraries(vm-exec PUBLIC ton_crypto terminal) +#target_compile_options(vm-exec PRIVATE -sMAIN_MODULE) +#target_compile_definitions(vm-exec PUBLIC -s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]') +#target_link_options(vm-exec PRIVATE -sEXPORTED_FUNCTIONS=['_test']) +if(EMSCRIPTEN) + target_link_options(vm-exec PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,allocate,free,intArrayFromString,ALLOC_NORMAL,UTF8ToString) + target_link_options(vm-exec PRIVATE -sMAIN_MODULE) + target_link_options(vm-exec PRIVATE -sERROR_ON_UNDEFINED_SYMBOLS=0) + target_link_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) +# target_link_options(vm-exec PRIVATE --pre-js /Users/altox/Desktop/js_playground/tonjs/pre.js) + target_compile_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) + #add_definitions("-s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]'") +endif() +if (WINGETOPT_FOUND) + target_link_libraries_system(func wingetop ton_crypto tdutils ton_crypto fift-lib) +endif() + +add_library(vm-exec-lib SHARED vm-exec/vm-exec-lib.cpp vm-exec/StringLog.h vm-exec/common.cpp vm-exec/common.h) +target_link_libraries(vm-exec-lib PUBLIC ton_crypto terminal) +if(EMSCRIPTEN) + target_link_options(vm-exec-lib PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,allocate,intArrayFromString,ALLOC_NORMAL,UTF8ToString) + target_link_options(vm-exec-lib PRIVATE -sMAIN_MODULE) + target_link_options(vm-exec-lib PRIVATE -sERROR_ON_UNDEFINED_SYMBOLS=0) + target_link_options(vm-exec-lib PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) + target_compile_options(vm-exec-lib PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) +endif() +set_target_properties(vm-exec-lib PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/vm-exec/vm-exec-lib_export_list") + +add_executable(wallet_gen wallet_gen/wallet_gen.cpp) +target_include_directories(wallet_gen PUBLIC $) +target_link_libraries(wallet_gen PUBLIC ton_crypto tonlib terminal) if (WINGETOPT_FOUND) target_link_libraries_system(func wingetop ton_crypto tdutils ton_crypto fift-lib) endif() @@ -414,7 +444,7 @@ target_include_directories(create-state PUBLIC $ + + +class StringLog : public td::LogInterface { + public: + StringLog() { + } + + void append(td::CSlice new_slice, int log_level) override { + lock.lock(); + this->str.append(new_slice.str()); + lock.unlock(); + } + + void rotate() override { + } + + void clear() { + this->str.clear(); + } + + std::string get_string() const { + return this->str; + } + + private: + std::string str; + std::mutex lock; +}; + +#endif //TON_STRINGLOG_H diff --git a/crypto/vm-exec/common.cpp b/crypto/vm-exec/common.cpp new file mode 100644 index 000000000..3a63f4c5a --- /dev/null +++ b/crypto/vm-exec/common.cpp @@ -0,0 +1,247 @@ +// +// Created by Narek Abovyan on 23.02.2022. +// + +#include "common.h" + +td::Ref prepare_vm_c7(ton::UnixTime now) { + // auto now = static_cast(td::Time::now()); + td::BitArray<256> rand_seed; + td::RefInt256 rand_seed_int{true}; + td::Random::secure_bytes(rand_seed.as_slice()); + if (!rand_seed_int.unique_write().import_bits(rand_seed.cbits(), 256, false)) { + return {}; + } + auto balance = block::CurrencyCollection{1000, {}}.as_vm_tuple(); + auto tuple = vm::make_tuple_ref(td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea + td::make_refint(0), // actions:Integer + td::make_refint(0), // msgs_sent:Integer + td::make_refint(now), // unixtime:Integer + td::make_refint(now), // block_lt:Integer + td::make_refint(now), // trans_lt:Integer + std::move(rand_seed_int), // rand_seed:Integer + balance // balance_remaining:[Integer (Maybe Cell)] + // my_addr, // myself:MsgAddressInt + // vm::StackEntry() // global_config:(Maybe Cell) ] = SmartContractInfo; + ); + LOG(DEBUG) << "SmartContractInfo initialized with " << vm::StackEntry(tuple).to_string(); + return vm::make_tuple_ref(std::move(tuple)); +} + +td::Result json_to_stack_entry(td::JsonObject &obj) { + TRY_RESULT(type, get_json_object_string_field(obj, "type")); + + if (type == "int") { + TRY_RESULT(data, get_json_object_string_field(obj, "value")); + return vm::StackEntry(td::dec_string_to_int256(data)); + } + if (type == "cell") { + TRY_RESULT(data, get_json_object_string_field(obj, "value")); + TRY_RESULT(data_bytes, td::base64_decode(data)); + TRY_RESULT(boc, vm::std_boc_deserialize(data_bytes)); + TRY_RESULT(data_cell, boc->load_cell()); + return vm::StackEntry(data_cell.data_cell); + } + if (type == "cell_slice") { + TRY_RESULT(data, get_json_object_string_field(obj, "value")); + TRY_RESULT(data_bytes, td::base64_decode(data)); + TRY_RESULT(boc, vm::std_boc_deserialize(data_bytes)); + TRY_RESULT(data_cell, boc->load_cell()); + return vm::StackEntry(td::make_ref(vm::CellSlice(data_cell))); + } + if (type == "null") { + return vm::StackEntry(); + } + if (type == "tuple") { + TRY_RESULT(data, td::get_json_object_field(obj, "value", td::JsonValue::Type::Array, false)); + auto &data_arr = data.get_array(); + + std::vector tuple_components; + + for (auto &x : data_arr) { + TRY_RESULT(item, json_to_stack_entry(x.get_object())); + tuple_components.push_back(item); + } + + return vm::StackEntry(tuple_components); + } + + return vm::StackEntry(); +} + +td::Result> json_to_stack(td::JsonArray &array) { + auto stack = td::make_ref(); + + for (auto &x : array) { + auto &obj = x.get_object(); + TRY_RESULT(entry, json_to_stack_entry(obj)); + stack.write().push(entry); + } + + return stack; +} + +td::Result stack_entry_to_json(vm::StackEntry se) { + if (se.is_int()) { + return R"({ "type": "int", "value": ")" + td::dec_string(se.as_int()) + R"("})"; + } + if (se.is_cell()) { + TRY_RESULT(boc, vm::std_boc_serialize(se.as_cell())); + auto value = td::base64_encode(boc); + return R"({ "type": "cell", "value": ")" + value + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_slice) { + vm::CellBuilder b; + b.append_cellslice(se.as_slice()); + TRY_RESULT(boc, vm::std_boc_serialize(b.finalize())); + auto value = td::base64_encode(boc); + return R"({ "type": "cell_slice", "value": ")" + value + R"("})"; + } + if (se.is_null()) { + return R"({ "type": "null" })"; + } + if (se.is_tuple()) { + std::string res = R"({ "type": "tuple", "value": [)"; + + auto tuple = se.as_tuple(); + + for (auto &x : *tuple) { + TRY_RESULT(item, stack_entry_to_json(x)); + res.append(item); + res.append(","); + } + res = res.substr(0, res.length() - 1); + res += "] }"; + + return res; + } + + // + // Non supported by TVM + // + if (se.type() == vm::StackEntry::Type::t_builder) { + return R"({ "type": "t_builder" })"; + } + if (se.type() == vm::StackEntry::Type::t_vmcont) { + return R"({ "type": "t_vmcont" })"; + } + if (se.type() == vm::StackEntry::Type::t_string) { + return R"({ "type": "string", value: ")" + se.as_string() + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_bytes) { + return R"({ "type": "bytes", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; + } + if (se.type() == vm::StackEntry::Type::t_bitstring) { + return R"({ "type": "bitstring", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; + } + + return R"({ "type": "unknown" })"; +} + +td::Result stack2json(vm::Ref stack) { + if (stack->is_empty()) { + return "[]"; + } + std::string out = "["; + for (const auto &x : stack->as_span()) { + TRY_RESULT(item, stack_entry_to_json(x)); + out.append(item); + out.append(","); + } + out = out.substr(0, out.length() - 1); + out.append("]"); + return out; +} + +td::Result run_vm(td::Ref code, td::Ref data, td::JsonArray &stack_array, + td::JsonObject &c7_register, int function_selector, + std::function getLogs) { + vm::init_op_cp0(true); + + TRY_RESULT(stack, json_to_stack(stack_array)); + TRY_RESULT(c7_data, json_to_stack_entry(c7_register)); + + td::int64 method_id = function_selector; + stack.write().push_smallint(method_id); + + long long gas_limit = vm::GasLimits::infty; + vm::GasLimits gas{gas_limit}; + LOG(DEBUG) << "creating VM"; + vm::VmState vm{std::move(code), std::move(stack), gas, 1, data, vm::VmLog()}; + + vm.set_c7(c7_data.as_tuple()); + + LOG(DEBUG) << "SmartContractInfo initialized with " << vm::StackEntry(vm.get_c7()).to_string(); + LOG(INFO) << "starting VM to run method `" << function_selector << "` of smart contract"; + + int exit_code; + try { + exit_code = ~vm.run(); + } catch (vm::VmVirtError &err) { + LOG(ERROR) << "virtualization error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + } catch (vm::VmError &err) { + LOG(ERROR) << "error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + } + + if (exit_code != 0) { + auto serialized_logs = td::base64_encode(getLogs()); + + std::string result; + result += "{"; + result += R"("ok": true,)"; + result += R"("exit_code":)" + std::to_string(exit_code) + ","; + result += R"("logs": ")" + serialized_logs + R"(")"; + result += "}"; + + return result; + } + + stack = vm.get_stack_ref(); + + std::string result; + + auto committed_state = vm.get_committed_state(); + + TRY_RESULT(data_cell_boc, vm::std_boc_serialize(committed_state.c4)); + auto serialized_data_cell = td::base64_encode(data_cell_boc); + TRY_RESULT(action_list_boc, vm::std_boc_serialize(committed_state.c5)); + auto serialized_action_list_cell = td::base64_encode(action_list_boc); + auto serialized_logs = td::base64_encode(getLogs()); + TRY_RESULT(stack_str, stack2json(stack)); + + result += "{"; + result += R"("ok": true,)"; + result += R"("exit_code":)" + std::to_string(exit_code) + ","; + result += R"("stack":)" + stack_str + ","; + result += R"("data_cell": ")" + serialized_data_cell + R"(",)"; + result += R"("gas_consumed": )" + std::to_string(vm.gas_consumed()) + R"(,)"; + result += R"("action_list_cell": ")" + serialized_action_list_cell + R"(",)"; + result += R"("logs": ")" + serialized_logs + R"(")"; + result += "}"; + + return result; +} + +td::Result vm_exec_from_config(std::string config, std::function getLogs) { + TRY_RESULT(input_json, td::json_decode(config)) + auto &obj = input_json.get_object(); + + TRY_RESULT(code, td::get_json_object_string_field(obj, "code", false)); + TRY_RESULT(data, td::get_json_object_string_field(obj, "data", false)); + TRY_RESULT(function_selector, td::get_json_object_int_field(obj, "function_selector", false)); + TRY_RESULT(initial_stack, td::get_json_object_field(obj, "init_stack", td::JsonValue::Type::Array, false)); + TRY_RESULT(c7_register, td::get_json_object_field(obj, "c7_register", td::JsonValue::Type::Object, false)); + + auto &initial_stack_array = initial_stack.get_array(); + + TRY_RESULT(data_bytes, td::base64_decode(data)); + TRY_RESULT(boc, vm::std_boc_deserialize(data_bytes)); + TRY_RESULT(data_cell, boc->load_cell()); + + TRY_RESULT(decoded_code, td::base64_decode(code)); + TRY_RESULT(code_boc, vm::std_boc_deserialize(decoded_code)); + TRY_RESULT(code_cell, code_boc->load_cell()); + + return run_vm(code_cell.data_cell, data_cell.data_cell, initial_stack_array, c7_register.get_object(), + function_selector, getLogs); +} \ No newline at end of file diff --git a/crypto/vm-exec/common.h b/crypto/vm-exec/common.h new file mode 100644 index 000000000..8d03908be --- /dev/null +++ b/crypto/vm-exec/common.h @@ -0,0 +1,39 @@ +// +// Created by Narek Abovyan on 23.02.2022. +// + +#ifndef TON_COMMON_H +#define TON_COMMON_H + +#include "vm/vm.h" +#include "vm/cp0.h" +#include "vm/boc.h" +#include "vm/stack.hpp" +#include "crypto/block/block.h" +#include "td/utils/base64.h" +#include "td/utils/ScopeGuard.h" +#include "terminal/terminal.h" +#include "td/utils/Random.h" +#include "td/utils/filesystem.h" +#include "td/utils/JsonBuilder.h" +#include "td/utils/OptionParser.h" +#include "td/utils/logging.h" +#include "StringLog.h" + + +td::Ref prepare_vm_c7(ton::UnixTime now); + +td::Result json_to_stack_entry(td::JsonObject &obj); + +td::Result> json_to_stack(td::JsonArray &array); + +td::Result stack_entry_to_json(vm::StackEntry se); + +td::Result stack2json(vm::Ref stack); + +td::Result run_vm(td::Ref code_cell, td::Ref data, td::JsonArray &stack_array, td::JsonObject &c7_register, + int function_selector, std::function getLogs); + +td::Result vm_exec_from_config(std::string config, std::function getLogs); + +#endif //TON_COMMON_H diff --git a/crypto/vm-exec/vm-exec-lib.cpp b/crypto/vm-exec/vm-exec-lib.cpp new file mode 100644 index 000000000..0296cc5d2 --- /dev/null +++ b/crypto/vm-exec/vm-exec-lib.cpp @@ -0,0 +1,37 @@ +#include "vm/cp0.h" +#include "td/utils/logging.h" +#include "StringLog.h" +#include "common.h" + +using namespace std::literals::string_literals; + +auto memLog = new StringLog(); + +class NoopLog : public td::LogInterface { + public: + void append(td::CSlice slice) override { + } +}; + +extern "C" char *vm_exec(int len, char *_data) { + // Init logging + td::log_interface = memLog; + SET_VERBOSITY_LEVEL(verbosity_DEBUG); + memLog->clear(); + + std::string config(_data, len); + + auto res = vm_exec_from_config(config, []() -> std::string { return memLog->get_string(); }); + + if (res.is_error()) { + std::string result; + result += "{"; + result += R"("ok": false,)"; + result += R"("error": ")" + res.move_as_error().message().str() + R"(")"; + result += "}"; + + return strdup(result.c_str()); + } + + return strdup(res.move_as_ok().c_str()); +} \ No newline at end of file diff --git a/crypto/vm-exec/vm-exec-lib_export_list b/crypto/vm-exec/vm-exec-lib_export_list new file mode 100644 index 000000000..c0f8ddca2 --- /dev/null +++ b/crypto/vm-exec/vm-exec-lib_export_list @@ -0,0 +1 @@ +_vm_exec \ No newline at end of file diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index df717843c..c5c31619a 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -1,259 +1,80 @@ -#include "vm/vm.h" #include "vm/cp0.h" -#include "vm/boc.h" -#include "vm/stack.hpp" -#include "fift/utils.h" -#include "crypto/block/block.h" -#include "td/utils/base64.h" -#include "td/utils/ScopeGuard.h" -#include "terminal/terminal.h" -#include "td/utils/Random.h" -#include "td/utils/Time.h" -#include "td/utils/filesystem.h" -#include "td/utils/JsonBuilder.h" -#include "td/utils/OptionParser.h" +#include "td/utils/logging.h" +#include "StringLog.h" +#include "common.h" +#include using namespace std::literals::string_literals; -td::Ref prepare_vm_c7() { - auto now = static_cast(td::Time::now()); - td::BitArray<256> rand_seed; - td::RefInt256 rand_seed_int{true}; - td::Random::secure_bytes(rand_seed.as_slice()); - if (!rand_seed_int.unique_write().import_bits(rand_seed.cbits(), 256, false)) { - return {}; - } - auto balance = block::CurrencyCollection{1000, {}}.as_vm_tuple(); - auto tuple = vm::make_tuple_ref( - td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea - td::make_refint(0), // actions:Integer - td::make_refint(0), // msgs_sent:Integer - td::make_refint(now), // unixtime:Integer - td::make_refint(now), // block_lt:Integer - td::make_refint(now), // trans_lt:Integer - std::move(rand_seed_int), // rand_seed:Integer - balance // balance_remaining:[Integer (Maybe Cell)] - // my_addr, // myself:MsgAddressInt - // vm::StackEntry() // global_config:(Maybe Cell) ] = SmartContractInfo; - ); - LOG(DEBUG) << "SmartContractInfo initialized with " << vm::StackEntry(tuple).to_string(); - return vm::make_tuple_ref(std::move(tuple)); -} - -vm::StackEntry json_to_stack_entry(td::JsonObject& obj) { - auto type = get_json_object_string_field(obj, "type").move_as_ok(); - - if (type == "int") { - auto data = get_json_object_string_field(obj, "value").move_as_ok(); - return vm::StackEntry(td::dec_string_to_int256(data)); - } - if (type == "cell") { - auto data = get_json_object_string_field(obj, "value").move_as_ok(); - auto data_bytes = td::base64_decode(data).move_as_ok(); - auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); - auto data_cell = boc->load_cell().move_as_ok(); - return vm::StackEntry(data_cell.data_cell); - } - if (type == "cell_slice") { - auto data = get_json_object_string_field(obj, "value").move_as_ok(); - auto data_bytes = td::base64_decode(data).move_as_ok(); - auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); - auto data_cell = boc->load_cell().move_as_ok(); - return vm::StackEntry(td::make_ref(vm::CellSlice(data_cell))); - } - if (type == "null") { - return vm::StackEntry(); - } - if (type == "tuple") { - auto data = td::get_json_object_field(obj, "value", td::JsonValue::Type::Array, false).move_as_ok(); - auto& data_arr = data.get_array(); - - std::vector tuple_components; - - for (auto& x : data_arr) { - tuple_components.push_back(json_to_stack_entry(x.get_object())); - } - - return vm::StackEntry(tuple_components); - } - - return vm::StackEntry(); -} - -td::Ref json_to_stack(td::JsonArray& array) { - auto stack = td::make_ref(); - - for (auto& x : array) { - auto& obj = x.get_object(); - auto entry = json_to_stack_entry(obj); - stack.write().push(entry); - } - - return stack; -} - -std::string stack_entry_to_json(vm::StackEntry se) { - if (se.is_int()) { - return R"({ "type": "int", "value": ")" + td::dec_string(se.as_int()) + R"("})"; - } - if (se.is_cell()) { - auto value = td::base64_encode(vm::std_boc_serialize(se.as_cell()).move_as_ok()); - return R"({ "type": "cell", "value": ")" + value + R"("})"; - } - if (se.type() == vm::StackEntry::Type::t_slice) { - vm::CellBuilder b; - b.append_cellslice(se.as_slice()); - auto value = td::base64_encode(vm::std_boc_serialize(b.finalize()).move_as_ok()); - // auto value = td::base64_encode(vm::std_boc_serialize(se.as_slice()->get_base_cell()).move_as_ok()); - return R"({ "type": "cell_slice", "value": ")" + value + R"("})"; - } - if (se.is_null()) { - return R"({ "type": "null" })"; - } - if (se.is_tuple()) { - std::string res = R"({ "type": "tuple", "value": [)"; - - auto tuple = se.as_tuple(); - - for (auto& x : *tuple) { - res.append(stack_entry_to_json(x)); - res.append(","); - } - res = res.substr(0, res.length() - 1); - res += "] }"; - - return res; - } - - // - // Non supported by TVM - // - if (se.type() == vm::StackEntry::Type::t_builder) { - return se.as_builder()->to_hex(); - } - if (se.type() == vm::StackEntry::Type::t_vmcont) { - return R"({ "type": "t_vmcont" })"; - } - if (se.type() == vm::StackEntry::Type::t_string) { - return R"({ "type": "string", value: ")" + se.as_string() + R"("})"; - } - if (se.type() == vm::StackEntry::Type::t_bytes) { - return R"({ "type": "bytes", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; - } - if (se.type() == vm::StackEntry::Type::t_bitstring) { - return R"({ "type": "bitstring", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; - } +auto memLog = new StringLog(); - return R"({ "type": "unknown" })"; -} - -std::string stack2json(vm::Ref stack) { - if (stack->is_empty()) { - return "[]"; - } - std::string out = "["; - for (const auto& x : stack->as_span()) { - out.append(stack_entry_to_json(x)); - out.append(","); - } - out = out.substr(0, out.length() - 1); - out.append("]"); - return out; -} - -std::string run_vm(td::Ref code_cell, td::Ref data, td::JsonArray& stack_array, int function_selector) { - auto code = code_cell; - - vm::init_op_cp0(); - - auto stack = json_to_stack(stack_array); - - td::int64 method_id = function_selector; - stack.write().push_smallint(method_id); - - long long gas_limit = vm::GasLimits::infty; - vm::GasLimits gas{gas_limit}; - LOG(DEBUG) << "creating VM"; - vm::VmState vm{code, std::move(stack), gas, 1, data, vm::VmLog()}; - vm.set_c7(prepare_vm_c7()); // tuple with SmartContractInfo - LOG(INFO) << "starting VM to run method `" << 0 << "` (" << 0 << ") of smart contract " << 0; - - int exit_code; - try { - exit_code = ~vm.run(); - } catch (vm::VmVirtError& err) { - LOG(ERROR) << "virtualization error while running VM to locally compute runSmcMethod result: " << err.get_msg(); - } catch (vm::VmError& err) { - LOG(ERROR) << "error while running VM to locally compute runSmcMethod result: " << err.get_msg(); - } +extern "C" char *vm_exec(int len, char *_data) { + // Init logging + td::log_interface = memLog; + SET_VERBOSITY_LEVEL(verbosity_DEBUG); + memLog->clear(); - if (exit_code != 0) { - return R"({ "exit_code": )" + std::to_string(exit_code) + "}"; - } + std::string config(_data, len); - stack = vm.get_stack_ref(); + auto res = vm_exec_from_config(config, []() -> std::string { return memLog->get_string(); }); + if (res.is_error()) { std::string result; - - auto committed_state = vm.get_committed_state(); - - auto serialized_data_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c4).move_as_ok()); - auto serialized_action_list_cell = td::base64_encode(vm::std_boc_serialize(committed_state.c5).move_as_ok()); - result += "{"; - result += R"("exit_code":)" + std::to_string(exit_code) + ","; - result += R"("stack":)" + stack2json(stack) + ","; - result += R"("data_cell": ")" + serialized_data_cell + R"(",)"; - result += R"("gas_consumed": )" + std::to_string(vm.gas_consumed()) + R"(,)"; - result += R"("action_list_cell": ")" + serialized_action_list_cell + R"(")"; + result += R"("ok": false,)"; + result += R"("error": ")" + res.move_as_error().message().str() + R"(")"; result += "}"; - return result; + return strdup(result.c_str()); + } + return strdup(res.move_as_ok().c_str()); } -void execute(td::Slice config_file_name) { - auto out = td::TerminalIO::out(); - - std::string input_file = config_file_name.str(); - auto input_data = td::read_file(input_file).move_as_ok().as_slice().str(); +void threadFunction() { + std::string config(R"({"function_selector":92067,"init_stack":[{"type":"int","value":"976"}],"code":"te6cckECFgEAArYAART/APSkE/S88sgLAQIBYgsCAgEgBgMCASAFBAAjuiF+1E0PpA0z/U1NT6QDBsUYACu5Bb7UTQ+kDTP9TU1PpAMF8D0NQwWIAgEgCgcCASAJCAAztPR9qJofSBpn+pqan0gGAgSr4L4AjgA+ALAANbXa/aiaH0gaZ/qamp9IBgKr4LoaYfph/0gGEABDuLXTHtRND6QNM/1NTU+kAwEDVfBdDUMNBxyMsHAc8WzMmAICzREMAgEgDg0Ag0UFTwBHAh8AUC0IIYLmpzb27IWM8WyyfJyMzJyFAGzxYVzCPPFlADzxbJd4AYyMsFUATPFlj6AhLLaxLMzMlx+wCAIBIBAPABs+QB0yMsCEsoHy//J0IAAtAHIyz/4KM8WyXAgyMsBE/QA9ADLAMmAE99EGOASK3wAOhpgYC42Eit8H0gGHaiaH0gaZ/qamp9IBgD6Y/pn8EINJ6cqCkYXUcVmBioK6+C6AlBCFRlgFa4QAhkZYKoAueLEn0BCmW1CeWP5Z+A54tkwCB9gHBBCB61w+OpGF1xgRiou2OC+XDIkGAA8YEQYAFxgRqCQVFBMSAEbAA44YBPpAMEQ1yFAGzxYUyz8SzMzMAc8Wye1U4F8GhA/y8AC2MHAG1DCOO4BA9JZvpSCOLQmkIIEA+r6T8sGP3oEBkyGgUyi78vQC+gDU+kAwI1E4QTMu8AYmupMFpAXeB5JsIeKz5jA1EDVVEshQBs8WFMs/EszMzAHPFsntVAB6MDIzA9M/UxK78uGSUxK6AfoA1PpAMFQkY1R1OfAGAY4YAqRFREMTyFAGzxYUyz8SzMzMAc8Wye1Ukl8G4gCMbGJSJMcF8uGTAtQwIPsE0O0e7VNwghBcuzqOVQJtgEBwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7ABUQGFw=","data":"te6cckECGwEABDMAA5WAADDwSC1LkiUbxtayDrG9enuDC8tUOxHJClfvnQPK7VUgAAAAAAABOJADrLq+X6jKZNHAScgghh0h1iog3StK71zn8dcmrOj8jPYZAgEASwAFAGSAADDwSC1LkiUbxtayDrG9enuDC8tUOxHJClfvnQPK7VUwART/APSkE/S88sgLAwIBYg0EAgFYBgUAEbohfwAhAoXwiAIBIAgHAA20Xr4ATZAwAgFICgkADa/n+AEvgkACASAMCwAQqUbwAhA4XwgADqp98AIYXwgCAs4RDgIBIBAPAD0yFAEzxZYzxbLBwHPFskEyMs/UAPPFgHPFszMye1UgAFs7UTQ0z/6QCDXScIAjhL6QNTUMND6QPpA0wf6QDB/VXDgMHBtbW1tJBBXEFZtgAvNDIhxwCSXwPg0NMD+kAw8AIIs45SN18ENDVSIscF8uGVAvpA1PpA+kAwcMjLA8nQJBB4Q4jwA3AgghBQdW5rbXFwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7AOAK0x8hwADjAApxsJJfDOAJ0z+BgSBP6CEF/MPRRSsLqOjTo6EFkQSBA3XjIQNFjgMzuCEC/LJqJSkLqOPV8EMjMzcIIQi3cXNQPIy/9QBM8WFIBAcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wDgghD1MNhnUpC64wJQll8GghA9a4fHE7rjAl8EFhUUEwAIhA/y8ACIUgLHBfLhkwHUMCD7BNDtHu1TcIIQXLs6jlUCbYBAcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wAAlDj6QDAkUWQGEEUQNBAjSarwA3CCEK9XPYQEyMv/UAPPFl4hcXCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAAfYwUUbHBfLhkQH6QPpA0gAx+gCCEAQsHYAcoSGhIMIA8uGSIY48ghAFE42RyCrPFlANzxZxJQROE1RI8HCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAkjsw4iDXCwHDAJMwMjfjDRBWBEUVA3AB8AMXAGSCENUydttKAwRtcXCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsABgCyU5XHBfLhkdMfAYIQc2VsbLqORVR3Y1R3ZXEs8ANwghAFE42RIcgpzxYkzxYnVTBxcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wDyAN4BABoAumh0dHBzOi8vY2xvdWRmbGFyZS1pcGZzLmNvbS9pcGZzL2JhZnliZWloem13N3NvYm50cGF0cTd6eWFrcHB0eTJjeDU0azNzaTV5aTI3Nm5hcXhseTducmI3amplL2PV5Lk=","c7_register":{"type":"tuple","value":[{"type":"tuple","value":[{"type":"int","value":"124711402"},{"type":"int","value":"0"},{"type":"int","value":"0"},{"type":"int","value":"1647206289"},{"type":"int","value":"1647206289"},{"type":"int","value":"1647206289"},{"type":"int","value":"405448960944048076912533454474163447403335447360159618829009007772079104040"},{"type":"tuple","value":[{"type":"int","value":"1000"},{"type":"null"}]},{"type":"cell_slice","value":"te6cckEBAQEAJAAAQ4AeGKizerOKjVdMf0ygusGYf8afGUSTg8X6pfID2a0dhjBlV57O"},{"type":"cell","value":"te6cckEBAQEAAgAAAEysuc0="}]}]}})"); - auto input_json = td::json_decode(input_data).move_as_ok(); - auto& obj = input_json.get_object(); - - auto code = td::get_json_object_string_field(obj, "code", false).move_as_ok(); - auto data = td::get_json_object_string_field(obj, "data", false).move_as_ok(); - auto function_selector = td::get_json_object_int_field(obj, "function_selector", false).move_as_ok(); - auto initial_stack = td::get_json_object_field(obj, "init_stack", td::JsonValue::Type::Array, false).move_as_ok(); - - auto& initial_stack_array = initial_stack.get_array(); +// for (int i = 0; i < 1000; ++i) { + char* res = vm_exec(strlen(config.c_str()), (char*)config.c_str()); + printf("%s\n", res); +// } +} - auto data_bytes = td::base64_decode(data).move_as_ok(); - auto boc = vm::std_boc_deserialize(data_bytes).move_as_ok(); - auto data_cell = boc->load_cell().move_as_ok(); +int main(int argc, char *argv[]) { - auto decoded_code = td::base64_decode(code).move_as_ok(); - auto code_boc = vm::std_boc_deserialize(decoded_code).move_as_ok(); - auto code_cell = code_boc->load_cell().move_as_ok(); - auto res = run_vm(code_cell.data_cell, data_cell.data_cell, initial_stack_array, function_selector); - out << res; -} -int main(int argc, char* argv[]) { - SET_VERBOSITY_LEVEL(verbosity_FATAL); + for (int i = 0; i < 1000; ++i) { + std::thread thr(threadFunction); + thr.join(); + } - td::OptionParser p; - p.set_description("TVM JSON Executor"); - p.add_option('h', "help", "prints_help", [&]() { - char b[10240]; - td::StringBuilder sb(td::MutableSlice{b, 10000}); - sb << p; - std::cout << sb.as_cslice().c_str(); - std::exit(2); - }); - p.add_option('c', "config", "path to config", [&](td::Slice fname) { execute(fname); }); - p.run(argc, argv).ensure(); +// td::log_interface = memLog; +// SET_VERBOSITY_LEVEL(verbosity_DEBUG); +// memLog->clear(); +// +// auto res = vm_exec_from_config(config, []() -> std::string { return memLog->get_string(); }); +// printf("%s", res.c_str()); - return 0; + return 0; } +//int main(int argc, char *argv[]) { +// SET_VERBOSITY_LEVEL(verbosity_FATAL); +// +// td::OptionParser p; +// +// p.set_description("TVM JSON Executor"); +// p.add_option('h', "help", "prints_help", [&]() { +// char b[10240]; +// td::StringBuilder sb(td::MutableSlice{b, 10000}); +// sb << p; +// std::cout << sb.as_cslice().c_str(); +// std::exit(2); +// }); +// p.add_option('c', "config", "path to config", [&](td::Slice fname) { execute(fname); }); +// p.run(argc, argv).ensure(); +// +// printf("%d\n", argc); +// printf("hello\n"); +// return 0; +//} diff --git a/crypto/wallet_gen/wallet_gen.cpp b/crypto/wallet_gen/wallet_gen.cpp new file mode 100644 index 000000000..de9027f11 --- /dev/null +++ b/crypto/wallet_gen/wallet_gen.cpp @@ -0,0 +1,30 @@ +#include +#include +#include "tonlib/keys/Mnemonic.h" + +using namespace tonlib; + +int main(int argc, char *argv[]) { + auto out = td::TerminalIO::out(); + + auto bip_words = Mnemonic::normalize_and_split(td::SecureString(bip39_english())); + + for (int i = 0; i <= 1000; i++ ){ + std::vector words; + for (int i = 0; i < 24; i++) { + words.push_back(bip_words[std::rand() % bip_words.size()].copy()); + } + + td::SecureString pass; + auto m = Mnemonic::create(std::move(words), pass.copy()).move_as_ok(); + +// Mnemonic::Options options; +// auto c = Mnemonic::create_new(std::move(options)).move_as_ok(); + td::Timer timer; + auto private_key = m.to_private_key().as_octet_string(); + LOG(INFO) << "Mnemonic generation debug stats: " << timer; + LOG(INFO) << private_key; +// out << "\n"; + } + +} \ No newline at end of file diff --git a/tdutils/td/utils/port/config.h b/tdutils/td/utils/port/config.h index 2bd671b01..383576d29 100644 --- a/tdutils/td/utils/port/config.h +++ b/tdutils/td/utils/port/config.h @@ -62,4 +62,11 @@ #define TD_HAS_MMSG 1 #endif + +#if TD_EMSCRIPTEN + #define TD_POLL_EPOLL 1 + #define TD_EVENTFD_UNSUPPORTED 0 + #define TD_THREAD_PTHREAD 1 + #define TD_EVENTFD_LINUX 1 +#endif // clang-format on diff --git a/tonlib/CMakeLists.txt b/tonlib/CMakeLists.txt index 5b6530a67..b52f13cf2 100644 --- a/tonlib/CMakeLists.txt +++ b/tonlib/CMakeLists.txt @@ -149,11 +149,11 @@ endif() install(FILES ${TONLIB_JSON_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/tonlib/tonlibjson_export.h DESTINATION include/tonlib/) -install(EXPORT Tonlib - FILE TonlibTargets.cmake - NAMESPACE Tonlib:: - DESTINATION lib/cmake/Tonlib -) +#install(EXPORT Tonlib +# FILE TonlibTargets.cmake +# NAMESPACE Tonlib:: +# DESTINATION lib/cmake/Tonlib +#) include(CMakePackageConfigHelpers) write_basic_package_version_file("TonlibConfigVersion.cmake" VERSION ${TON_VERSION} From 6d68036ff732b7ae26653b38c683be8dc948ea68 Mon Sep 17 00:00:00 2001 From: altox Date: Thu, 7 Apr 2022 01:07:12 +0300 Subject: [PATCH 07/12] cleanup code --- crypto/vm-exec/vm-exec.cpp | 52 +------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index c5c31619a..22b334b4f 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -2,7 +2,6 @@ #include "td/utils/logging.h" #include "StringLog.h" #include "common.h" -#include using namespace std::literals::string_literals; @@ -28,53 +27,4 @@ extern "C" char *vm_exec(int len, char *_data) { return strdup(result.c_str()); } return strdup(res.move_as_ok().c_str()); -} - -void threadFunction() { - std::string config(R"({"function_selector":92067,"init_stack":[{"type":"int","value":"976"}],"code":"te6cckECFgEAArYAART/APSkE/S88sgLAQIBYgsCAgEgBgMCASAFBAAjuiF+1E0PpA0z/U1NT6QDBsUYACu5Bb7UTQ+kDTP9TU1PpAMF8D0NQwWIAgEgCgcCASAJCAAztPR9qJofSBpn+pqan0gGAgSr4L4AjgA+ALAANbXa/aiaH0gaZ/qamp9IBgKr4LoaYfph/0gGEABDuLXTHtRND6QNM/1NTU+kAwEDVfBdDUMNBxyMsHAc8WzMmAICzREMAgEgDg0Ag0UFTwBHAh8AUC0IIYLmpzb27IWM8WyyfJyMzJyFAGzxYVzCPPFlADzxbJd4AYyMsFUATPFlj6AhLLaxLMzMlx+wCAIBIBAPABs+QB0yMsCEsoHy//J0IAAtAHIyz/4KM8WyXAgyMsBE/QA9ADLAMmAE99EGOASK3wAOhpgYC42Eit8H0gGHaiaH0gaZ/qamp9IBgD6Y/pn8EINJ6cqCkYXUcVmBioK6+C6AlBCFRlgFa4QAhkZYKoAueLEn0BCmW1CeWP5Z+A54tkwCB9gHBBCB61w+OpGF1xgRiou2OC+XDIkGAA8YEQYAFxgRqCQVFBMSAEbAA44YBPpAMEQ1yFAGzxYUyz8SzMzMAc8Wye1U4F8GhA/y8AC2MHAG1DCOO4BA9JZvpSCOLQmkIIEA+r6T8sGP3oEBkyGgUyi78vQC+gDU+kAwI1E4QTMu8AYmupMFpAXeB5JsIeKz5jA1EDVVEshQBs8WFMs/EszMzAHPFsntVAB6MDIzA9M/UxK78uGSUxK6AfoA1PpAMFQkY1R1OfAGAY4YAqRFREMTyFAGzxYUyz8SzMzMAc8Wye1Ukl8G4gCMbGJSJMcF8uGTAtQwIPsE0O0e7VNwghBcuzqOVQJtgEBwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7ABUQGFw=","data":"te6cckECGwEABDMAA5WAADDwSC1LkiUbxtayDrG9enuDC8tUOxHJClfvnQPK7VUgAAAAAAABOJADrLq+X6jKZNHAScgghh0h1iog3StK71zn8dcmrOj8jPYZAgEASwAFAGSAADDwSC1LkiUbxtayDrG9enuDC8tUOxHJClfvnQPK7VUwART/APSkE/S88sgLAwIBYg0EAgFYBgUAEbohfwAhAoXwiAIBIAgHAA20Xr4ATZAwAgFICgkADa/n+AEvgkACASAMCwAQqUbwAhA4XwgADqp98AIYXwgCAs4RDgIBIBAPAD0yFAEzxZYzxbLBwHPFskEyMs/UAPPFgHPFszMye1UgAFs7UTQ0z/6QCDXScIAjhL6QNTUMND6QPpA0wf6QDB/VXDgMHBtbW1tJBBXEFZtgAvNDIhxwCSXwPg0NMD+kAw8AIIs45SN18ENDVSIscF8uGVAvpA1PpA+kAwcMjLA8nQJBB4Q4jwA3AgghBQdW5rbXFwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7AOAK0x8hwADjAApxsJJfDOAJ0z+BgSBP6CEF/MPRRSsLqOjTo6EFkQSBA3XjIQNFjgMzuCEC/LJqJSkLqOPV8EMjMzcIIQi3cXNQPIy/9QBM8WFIBAcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wDgghD1MNhnUpC64wJQll8GghA9a4fHE7rjAl8EFhUUEwAIhA/y8ACIUgLHBfLhkwHUMCD7BNDtHu1TcIIQXLs6jlUCbYBAcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wAAlDj6QDAkUWQGEEUQNBAjSarwA3CCEK9XPYQEyMv/UAPPFl4hcXCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAAfYwUUbHBfLhkQH6QPpA0gAx+gCCEAQsHYAcoSGhIMIA8uGSIY48ghAFE42RyCrPFlANzxZxJQROE1RI8HCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAkjsw4iDXCwHDAJMwMjfjDRBWBEUVA3AB8AMXAGSCENUydttKAwRtcXCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsABgCyU5XHBfLhkdMfAYIQc2VsbLqORVR3Y1R3ZXEs8ANwghAFE42RIcgpzxYkzxYnVTBxcIAQyMsFUAfPFlAF+gIVy2oSyx/LPyJus5RYzxcBkTLiAckB+wDyAN4BABoAumh0dHBzOi8vY2xvdWRmbGFyZS1pcGZzLmNvbS9pcGZzL2JhZnliZWloem13N3NvYm50cGF0cTd6eWFrcHB0eTJjeDU0azNzaTV5aTI3Nm5hcXhseTducmI3amplL2PV5Lk=","c7_register":{"type":"tuple","value":[{"type":"tuple","value":[{"type":"int","value":"124711402"},{"type":"int","value":"0"},{"type":"int","value":"0"},{"type":"int","value":"1647206289"},{"type":"int","value":"1647206289"},{"type":"int","value":"1647206289"},{"type":"int","value":"405448960944048076912533454474163447403335447360159618829009007772079104040"},{"type":"tuple","value":[{"type":"int","value":"1000"},{"type":"null"}]},{"type":"cell_slice","value":"te6cckEBAQEAJAAAQ4AeGKizerOKjVdMf0ygusGYf8afGUSTg8X6pfID2a0dhjBlV57O"},{"type":"cell","value":"te6cckEBAQEAAgAAAEysuc0="}]}]}})"); - -// for (int i = 0; i < 1000; ++i) { - char* res = vm_exec(strlen(config.c_str()), (char*)config.c_str()); - printf("%s\n", res); -// } -} - -int main(int argc, char *argv[]) { - - - - for (int i = 0; i < 1000; ++i) { - std::thread thr(threadFunction); - thr.join(); - } - - -// td::log_interface = memLog; -// SET_VERBOSITY_LEVEL(verbosity_DEBUG); -// memLog->clear(); -// -// auto res = vm_exec_from_config(config, []() -> std::string { return memLog->get_string(); }); -// printf("%s", res.c_str()); - - return 0; -} -//int main(int argc, char *argv[]) { -// SET_VERBOSITY_LEVEL(verbosity_FATAL); -// -// td::OptionParser p; -// -// p.set_description("TVM JSON Executor"); -// p.add_option('h', "help", "prints_help", [&]() { -// char b[10240]; -// td::StringBuilder sb(td::MutableSlice{b, 10000}); -// sb << p; -// std::cout << sb.as_cslice().c_str(); -// std::exit(2); -// }); -// p.add_option('c', "config", "path to config", [&](td::Slice fname) { execute(fname); }); -// p.run(argc, argv).ensure(); -// -// printf("%d\n", argc); -// printf("hello\n"); -// return 0; -//} +} \ No newline at end of file From 98c3747d8662af4aaad79f6faa221ba9020f6a84 Mon Sep 17 00:00:00 2001 From: altox Date: Thu, 7 Apr 2022 01:08:05 +0300 Subject: [PATCH 08/12] cleanup code --- crypto/vm-exec/vm-exec.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index 22b334b4f..46464a89f 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -2,6 +2,7 @@ #include "td/utils/logging.h" #include "StringLog.h" #include "common.h" +#include using namespace std::literals::string_literals; @@ -27,4 +28,8 @@ extern "C" char *vm_exec(int len, char *_data) { return strdup(result.c_str()); } return strdup(res.move_as_ok().c_str()); -} \ No newline at end of file +} + +int main(int argc, char *argv[]) { + return 0; +} From 39746a848af4022f9403d62ad8d200dc9c6a4bc3 Mon Sep 17 00:00:00 2001 From: altox Date: Thu, 7 Apr 2022 01:19:44 +0300 Subject: [PATCH 09/12] come fixes --- crypto/vm-exec/common.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/vm-exec/common.cpp b/crypto/vm-exec/common.cpp index 3a63f4c5a..ef9c72973 100644 --- a/crypto/vm-exec/common.cpp +++ b/crypto/vm-exec/common.cpp @@ -178,9 +178,11 @@ td::Result run_vm(td::Ref code, td::Ref data, t try { exit_code = ~vm.run(); } catch (vm::VmVirtError &err) { - LOG(ERROR) << "virtualization error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + LOG(ERROR) << "virtualization error while running VM: " << err.get_msg(); + exit_code = -1; } catch (vm::VmError &err) { - LOG(ERROR) << "error while running VM to locally compute runSmcMethod result: " << err.get_msg(); + LOG(ERROR) << "error while running VM: " << err.get_msg(); + exit_code = -1; } if (exit_code != 0) { From 9b3568d8ac7aad5974b0a1861bc1a5d3a4b08f87 Mon Sep 17 00:00:00 2001 From: Naltox Date: Mon, 18 Apr 2022 16:41:22 +0300 Subject: [PATCH 10/12] more work on executor: more optimized wasm build, debug ops now log to vmlog, fixed some config parsing stuff --- crypto/CMakeLists.txt | 17 +++++++---- crypto/vm-exec/common.cpp | 60 ++++++++++++++++++++++++-------------- crypto/vm-exec/common.h | 4 +++ crypto/vm-exec/vm-exec.cpp | 10 ++----- crypto/vm/debugops.cpp | 16 +++------- 5 files changed, 61 insertions(+), 46 deletions(-) diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index ac1a18c27..ed6f38096 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -309,17 +309,24 @@ endif() add_executable(vm-exec vm-exec/vm-exec.cpp vm-exec/StringLog.h vm-exec/common.cpp vm-exec/common.h) target_include_directories(vm-exec PUBLIC $) -target_link_libraries(vm-exec PUBLIC ton_crypto terminal) +target_link_libraries(vm-exec PUBLIC ton_crypto terminal) #target_compile_options(vm-exec PRIVATE -sMAIN_MODULE) #target_compile_definitions(vm-exec PUBLIC -s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]') #target_link_options(vm-exec PRIVATE -sEXPORTED_FUNCTIONS=['_test']) if(EMSCRIPTEN) - target_link_options(vm-exec PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,allocate,free,intArrayFromString,ALLOC_NORMAL,UTF8ToString) - target_link_options(vm-exec PRIVATE -sMAIN_MODULE) + target_link_options(vm-exec PRIVATE -sEXPORTED_RUNTIME_METHODS=free,allocate,intArrayFromString,ALLOC_NORMAL,UTF8ToString) + target_link_options(vm-exec PRIVATE -sEXPORTED_FUNCTIONS=_vm_exec,_free) +# target_link_options(vm-exec PRIVATE -sMAIN_MODULE) target_link_options(vm-exec PRIVATE -sERROR_ON_UNDEFINED_SYMBOLS=0) - target_link_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) +# target_link_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) + target_link_options(vm-exec PRIVATE -sFILESYSTEM=0) +# target_link_options(vm-exec PRIVATE -sWASM=0) + target_link_options(vm-exec PRIVATE -Oz) + target_link_options(vm-exec PRIVATE -sIGNORE_MISSING_MAIN=1) + target_link_options(vm-exec PRIVATE -sAUTO_NATIVE_LIBRARIES=0) + target_link_options(vm-exec PRIVATE -sMODULARIZE=1) # target_link_options(vm-exec PRIVATE --pre-js /Users/altox/Desktop/js_playground/tonjs/pre.js) - target_compile_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) +# target_compile_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) #add_definitions("-s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]'") endif() if (WINGETOPT_FOUND) diff --git a/crypto/vm-exec/common.cpp b/crypto/vm-exec/common.cpp index ef9c72973..b9aacb642 100644 --- a/crypto/vm-exec/common.cpp +++ b/crypto/vm-exec/common.cpp @@ -4,6 +4,29 @@ #include "common.h" +std::string escape_json(const std::string &s) { + std::ostringstream o; + for (auto c = s.cbegin(); c != s.cend(); c++) { + switch (*c) { + case '"': o << "\\\""; break; + case '\\': o << "\\\\"; break; + case '\b': o << "\\b"; break; + case '\f': o << "\\f"; break; + case '\n': o << "\\n"; break; + case '\r': o << "\\r"; break; + case '\t': o << "\\t"; break; + default: + if ('\x00' <= *c && *c <= '\x1f') { + o << "\\u" + << std::hex << std::setw(4) << std::setfill('0') << static_cast(*c); + } else { + o << *c; + } + } + } + return o.str(); +} + td::Ref prepare_vm_c7(ton::UnixTime now) { // auto now = static_cast(td::Time::now()); td::BitArray<256> rand_seed; @@ -73,6 +96,9 @@ td::Result> json_to_stack(td::JsonArray &array) { auto stack = td::make_ref(); for (auto &x : array) { + if (x.type() != td::JsonValue::Type::Object) { + return td::Status::Error(PSLICE() << "Stack item must be object"); + } auto &obj = x.get_object(); TRY_RESULT(entry, json_to_stack_entry(obj)); stack.write().push(entry); @@ -116,25 +142,6 @@ td::Result stack_entry_to_json(vm::StackEntry se) { return res; } - // - // Non supported by TVM - // - if (se.type() == vm::StackEntry::Type::t_builder) { - return R"({ "type": "t_builder" })"; - } - if (se.type() == vm::StackEntry::Type::t_vmcont) { - return R"({ "type": "t_vmcont" })"; - } - if (se.type() == vm::StackEntry::Type::t_string) { - return R"({ "type": "string", value: ")" + se.as_string() + R"("})"; - } - if (se.type() == vm::StackEntry::Type::t_bytes) { - return R"({ "type": "bytes", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; - } - if (se.type() == vm::StackEntry::Type::t_bitstring) { - return R"({ "type": "bitstring", value: ")" + td::base64_encode(se.as_bytes()) + R"("})"; - } - return R"({ "type": "unknown" })"; } @@ -175,17 +182,18 @@ td::Result run_vm(td::Ref code, td::Ref data, t LOG(INFO) << "starting VM to run method `" << function_selector << "` of smart contract"; int exit_code; + bool errored = false; try { exit_code = ~vm.run(); } catch (vm::VmVirtError &err) { LOG(ERROR) << "virtualization error while running VM: " << err.get_msg(); - exit_code = -1; + errored = true; } catch (vm::VmError &err) { LOG(ERROR) << "error while running VM: " << err.get_msg(); - exit_code = -1; + errored = true; } - if (exit_code != 0) { + if (exit_code != 0 && !errored) { auto serialized_logs = td::base64_encode(getLogs()); std::string result; @@ -228,6 +236,14 @@ td::Result vm_exec_from_config(std::string config, std::function +#include +std::string escape_json(const std::string &s); + td::Ref prepare_vm_c7(ton::UnixTime now); td::Result json_to_stack_entry(td::JsonObject &obj); diff --git a/crypto/vm-exec/vm-exec.cpp b/crypto/vm-exec/vm-exec.cpp index 46464a89f..0740acb54 100644 --- a/crypto/vm-exec/vm-exec.cpp +++ b/crypto/vm-exec/vm-exec.cpp @@ -2,7 +2,6 @@ #include "td/utils/logging.h" #include "StringLog.h" #include "common.h" -#include using namespace std::literals::string_literals; @@ -12,6 +11,7 @@ extern "C" char *vm_exec(int len, char *_data) { // Init logging td::log_interface = memLog; SET_VERBOSITY_LEVEL(verbosity_DEBUG); +// SET_VERBOSITY_LEVEL(verbosity_ERROR); memLog->clear(); std::string config(_data, len); @@ -22,14 +22,10 @@ extern "C" char *vm_exec(int len, char *_data) { std::string result; result += "{"; result += R"("ok": false,)"; - result += R"("error": ")" + res.move_as_error().message().str() + R"(")"; + result += R"("error": ")" + escape_json(res.move_as_error().message().str()) + R"(")"; result += "}"; return strdup(result.c_str()); } return strdup(res.move_as_ok().c_str()); -} - -int main(int argc, char *argv[]) { - return 0; -} +} \ No newline at end of file diff --git a/crypto/vm/debugops.cpp b/crypto/vm/debugops.cpp index 0ec205a31..b9558a160 100644 --- a/crypto/vm/debugops.cpp +++ b/crypto/vm/debugops.cpp @@ -75,16 +75,10 @@ int exec_dump_stack(VmState* st) { } Stack& stack = st->get_stack(); int d = stack.depth(); - std::cerr << "#DEBUG#: stack(" << d << " values) : "; - if (d > 255) { - std::cerr << "... "; - d = 255; - } + VM_LOG(st) << "#DEBUG#: stack(" << d << " values) : "; for (int i = d; i > 0; i--) { - stack[i - 1].print_list(std::cerr); - std::cerr << ' '; + VM_LOG(st) << "s" << i-1 << " = " << stack[i - 1].to_lisp_string(); } - std::cerr << std::endl; return 0; } @@ -96,11 +90,9 @@ int exec_dump_value(VmState* st, unsigned arg) { } Stack& stack = st->get_stack(); if ((int)arg < stack.depth()) { - std::cerr << "#DEBUG#: s" << arg << " = "; - stack[arg].print_list(std::cerr); - std::cerr << std::endl; + VM_LOG(st) << "#DEBUG#: s" << arg << " = " << stack[arg].to_lisp_string(); } else { - std::cerr << "#DEBUG#: s" << arg << " is absent" << std::endl; + VM_LOG(st) << "#DEBUG#: s" << arg << " is absent"; } return 0; } From 31be5700b7bb548201f65fdddb5531b42a8b2b47 Mon Sep 17 00:00:00 2001 From: Naltox Date: Mon, 18 Apr 2022 18:28:20 +0300 Subject: [PATCH 11/12] some fixes on makefile --- crypto/CMakeLists.txt | 10 +--------- crypto/vm-exec/common.cpp | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index ed6f38096..d14f0b443 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -310,24 +310,16 @@ endif() add_executable(vm-exec vm-exec/vm-exec.cpp vm-exec/StringLog.h vm-exec/common.cpp vm-exec/common.h) target_include_directories(vm-exec PUBLIC $) target_link_libraries(vm-exec PUBLIC ton_crypto terminal) -#target_compile_options(vm-exec PRIVATE -sMAIN_MODULE) -#target_compile_definitions(vm-exec PUBLIC -s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]') -#target_link_options(vm-exec PRIVATE -sEXPORTED_FUNCTIONS=['_test']) if(EMSCRIPTEN) target_link_options(vm-exec PRIVATE -sEXPORTED_RUNTIME_METHODS=free,allocate,intArrayFromString,ALLOC_NORMAL,UTF8ToString) target_link_options(vm-exec PRIVATE -sEXPORTED_FUNCTIONS=_vm_exec,_free) -# target_link_options(vm-exec PRIVATE -sMAIN_MODULE) target_link_options(vm-exec PRIVATE -sERROR_ON_UNDEFINED_SYMBOLS=0) -# target_link_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) target_link_options(vm-exec PRIVATE -sFILESYSTEM=0) -# target_link_options(vm-exec PRIVATE -sWASM=0) target_link_options(vm-exec PRIVATE -Oz) target_link_options(vm-exec PRIVATE -sIGNORE_MISSING_MAIN=1) target_link_options(vm-exec PRIVATE -sAUTO_NATIVE_LIBRARIES=0) target_link_options(vm-exec PRIVATE -sMODULARIZE=1) -# target_link_options(vm-exec PRIVATE --pre-js /Users/altox/Desktop/js_playground/tonjs/pre.js) -# target_compile_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) - #add_definitions("-s EXPORTED_FUNCTIONS='[\"_test\", \"test\"]'") + target_compile_options(vm-exec PRIVATE -sNO_DISABLE_EXCEPTION_CATCHING) endif() if (WINGETOPT_FOUND) target_link_libraries_system(func wingetop ton_crypto tdutils ton_crypto fift-lib) diff --git a/crypto/vm-exec/common.cpp b/crypto/vm-exec/common.cpp index b9aacb642..ee112620a 100644 --- a/crypto/vm-exec/common.cpp +++ b/crypto/vm-exec/common.cpp @@ -193,7 +193,7 @@ td::Result run_vm(td::Ref code, td::Ref data, t errored = true; } - if (exit_code != 0 && !errored) { + if (errored) { auto serialized_logs = td::base64_encode(getLogs()); std::string result; From 5f208ef3f348957e11d9cbf413633631d1a5ede4 Mon Sep 17 00:00:00 2001 From: Naltox Date: Tue, 19 Apr 2022 01:50:17 +0300 Subject: [PATCH 12/12] fix exception handling --- crypto/vm-exec/common.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/vm-exec/common.cpp b/crypto/vm-exec/common.cpp index ee112620a..c3c89184f 100644 --- a/crypto/vm-exec/common.cpp +++ b/crypto/vm-exec/common.cpp @@ -193,12 +193,12 @@ td::Result run_vm(td::Ref code, td::Ref data, t errored = true; } - if (errored) { + if (errored || exit_code != 0) { auto serialized_logs = td::base64_encode(getLogs()); std::string result; result += "{"; - result += R"("ok": true,)"; + result += R"("ok": false,)"; result += R"("exit_code":)" + std::to_string(exit_code) + ","; result += R"("logs": ")" + serialized_logs + R"(")"; result += "}";