diff --git a/emulator/emulator-extern.cpp b/emulator/emulator-extern.cpp index 811316db..e589032f 100644 --- a/emulator/emulator-extern.cpp +++ b/emulator/emulator-extern.cpp @@ -19,7 +19,8 @@ td::Result cell_to_boc_b64(td::Ref cell) { return td::base64_encode(boc.as_slice()); } -const char *success_response(std::string&& transaction, std::string&& new_shard_account, std::string&& vm_log, td::optional&& actions) { +const char *success_response(std::string&& transaction, std::string&& new_shard_account, std::string&& vm_log, + td::optional&& actions, double elapsed_time) { td::JsonBuilder jb; auto json_obj = jb.enter_object(); json_obj("success", td::JsonTrue()); @@ -31,6 +32,7 @@ const char *success_response(std::string&& transaction, std::string&& new_shard_ } else { json_obj("actions", td::JsonNull()); } + json_obj("elapsed_time", elapsed_time); json_obj.leave(); return strdup(jb.string_builder().as_cslice().c_str()); } @@ -44,13 +46,14 @@ const char *error_response(std::string&& error) { return strdup(jb.string_builder().as_cslice().c_str()); } -const char *external_not_accepted_response(std::string&& vm_log, int vm_exit_code) { +const char *external_not_accepted_response(std::string&& vm_log, int vm_exit_code, double elapsed_time) { td::JsonBuilder jb; auto json_obj = jb.enter_object(); json_obj("success", td::JsonFalse()); json_obj("error", "External message not accepted by smart contract"); json_obj("vm_log", std::move(vm_log)); json_obj("vm_exit_code", vm_exit_code); + json_obj("elapsed_time", elapsed_time); json_obj.leave(); return strdup(jb.string_builder().as_cslice().c_str()); } @@ -142,7 +145,8 @@ const char *transaction_emulator_emulate_transaction(void *transaction_emulator, auto external_not_accepted = dynamic_cast(emulation_result.get()); if (external_not_accepted) { - return external_not_accepted_response(std::move(external_not_accepted->vm_log), external_not_accepted->vm_exit_code); + return external_not_accepted_response(std::move(external_not_accepted->vm_log), external_not_accepted->vm_exit_code, + external_not_accepted->elapsed_time); } auto emulation_success = dynamic_cast(*emulation_result); @@ -168,7 +172,8 @@ const char *transaction_emulator_emulate_transaction(void *transaction_emulator, actions_boc_b64 = actions_boc_b64_result.move_as_ok(); } - return success_response(trans_boc_b64.move_as_ok(), new_shard_account_boc_b64.move_as_ok(), std::move(emulation_success.vm_log), std::move(actions_boc_b64)); + return success_response(trans_boc_b64.move_as_ok(), new_shard_account_boc_b64.move_as_ok(), std::move(emulation_success.vm_log), + std::move(actions_boc_b64), emulation_success.elapsed_time); } bool transaction_emulator_set_unixtime(void *transaction_emulator, uint32_t unixtime) { diff --git a/emulator/transaction-emulator.cpp b/emulator/transaction-emulator.cpp index 4a616418..a5fea51c 100644 --- a/emulator/transaction-emulator.cpp +++ b/emulator/transaction-emulator.cpp @@ -2,6 +2,7 @@ #include "transaction-emulator.h" #include "crypto/common/refcnt.hpp" #include "vm/cp0.h" +#include "tdutils/td/utils/Time.h" using td::Ref; using namespace std::string_literals; @@ -47,9 +48,12 @@ td::Result> TransactionEmu compute_phase_cfg.with_vm_log = true; compute_phase_cfg.vm_log_verbosity = vm_log_verbosity_; + double start_time = td::Time::now(); auto res = create_transaction(msg_root, &account, utime, lt, trans_type, &storage_phase_cfg, &compute_phase_cfg, &action_phase_cfg); + double elapsed = td::Time::now() - start_time; + if(res.is_error()) { return res.move_as_error_prefix("cannot run message on account "); } @@ -58,7 +62,7 @@ td::Result> TransactionEmu if (!trans->compute_phase->accepted && trans->in_msg_extern) { auto vm_log = trans->compute_phase->vm_log; auto vm_exit_code = trans->compute_phase->exit_code; - return std::make_unique(std::move(vm_log), vm_exit_code); + return std::make_unique(std::move(vm_log), vm_exit_code, elapsed); } if (!trans->serialize()) { @@ -70,7 +74,8 @@ td::Result> TransactionEmu return td::Status::Error(PSLICE() << "cannot commit new transaction for smart contract"); } - return std::make_unique(std::move(trans_root), std::move(account), std::move(trans->compute_phase->vm_log), std::move(trans->compute_phase->actions)); + return std::make_unique(std::move(trans_root), std::move(account), + std::move(trans->compute_phase->vm_log), std::move(trans->compute_phase->actions), elapsed); } td::Result TransactionEmulator::emulate_transaction(block::Account&& account, td::Ref original_trans) { diff --git a/emulator/transaction-emulator.h b/emulator/transaction-emulator.h index 025bfa93..02f875e2 100644 --- a/emulator/transaction-emulator.h +++ b/emulator/transaction-emulator.h @@ -25,26 +25,27 @@ public: struct EmulationResult { std::string vm_log; + double elapsed_time; - EmulationResult(std::string vm_log_) : vm_log(vm_log_) {} + EmulationResult(std::string vm_log_, double elapsed_time_) : vm_log(vm_log_), elapsed_time(elapsed_time_) {} virtual ~EmulationResult() = default; }; struct EmulationSuccess: EmulationResult { td::Ref transaction; block::Account account; - td::Ref actions; + td::Ref actions; - EmulationSuccess(td::Ref transaction_, block::Account account_, std::string vm_log_, td::Ref actions_) : - EmulationResult(vm_log_), transaction(transaction_), account(account_) , actions(actions_) + EmulationSuccess(td::Ref transaction_, block::Account account_, std::string vm_log_, td::Ref actions_, double elapsed_time_) : + EmulationResult(vm_log_, elapsed_time_), transaction(transaction_), account(account_) , actions(actions_) {} }; struct EmulationExternalNotAccepted: EmulationResult { int vm_exit_code; - EmulationExternalNotAccepted(std::string vm_log_, int vm_exit_code_) : - EmulationResult(vm_log_), vm_exit_code(vm_exit_code_) + EmulationExternalNotAccepted(std::string vm_log_, int vm_exit_code_, double elapsed_time_) : + EmulationResult(vm_log_, elapsed_time_), vm_exit_code(vm_exit_code_) {} };