diff --git a/src/common/error_codes.h b/src/common/error_codes.h index 934ac3bc..a9644517 100644 --- a/src/common/error_codes.h +++ b/src/common/error_codes.h @@ -37,5 +37,5 @@ #define API_RETURN_CODE_GENESIS_MISMATCH "GENESIS_MISMATCH" #define API_RETURN_CODE_DISCONNECTED "DISCONNECTED" #define API_RETURN_CODE_UNINITIALIZED "UNINITIALIZED" - - +#define API_RETURN_CODE_TX_IS_TOO_BIG "TX_IS_TOO_BIG" +#define API_RETURN_CODE_TX_REJECTED "TX_REJECTED" diff --git a/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts b/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts index a2dbdcd2..8821f055 100644 --- a/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts +++ b/src/gui/qt-daemon/html_source/src/app/_helpers/services/backend.service.ts @@ -56,45 +56,38 @@ export class BackendService { switch (error) { case 'NOT_ENOUGH_MONEY': error_translate = 'ERRORS.NOT_ENOUGH_MONEY'; + // error_translate = 'ERRORS.NO_MONEY'; maybe that one? + if (command === 'cancel_offer') { + error_translate = this.translate.instant('ERRORS.NO_MONEY_REMOVE_OFFER', { + 'fee': this.variablesService.default_fee, + 'currency': this.variablesService.defaultCurrency + }); + } break; case 'CORE_BUSY': - if (command !== 'get_all_aliases') { - error_translate = 'ERRORS.CORE_BUSY'; - } + error_translate = 'ERRORS.CORE_BUSY'; + break; + case 'BUSY': + error_translate = 'ERRORS.DAEMON_BUSY'; break; case 'OVERFLOW': if (command !== 'get_all_aliases') { error_translate = ''; } break; - case 'INTERNAL_ERROR:daemon is busy': - error_translate = 'ERRORS.DAEMON_BUSY'; - break; - case 'INTERNAL_ERROR:not enough money': - case 'INTERNAL_ERROR:NOT_ENOUGH_MONEY': - if (command === 'cancel_offer') { - error_translate = this.translate.instant('ERRORS.NO_MONEY_REMOVE_OFFER', { - 'fee': this.variablesService.default_fee, - 'currency': this.variablesService.defaultCurrency - }); - } else { - error_translate = 'ERRORS.NO_MONEY'; - } - break; case 'NOT_ENOUGH_OUTPUTS_FOR_MIXING': - case 'INTERNAL_ERROR:not enough outputs to mix': error_translate = 'ERRORS.NOT_ENOUGH_OUTPUTS_TO_MIX'; break; - case 'INTERNAL_ERROR:transaction is too big': + case 'TX_IS_TOO_BIG': error_translate = 'ERRORS.TRANSACTION_IS_TO_BIG'; break; - case 'INTERNAL_ERROR:Transfer attempt while daemon offline': + case 'DISCONNECTED': error_translate = 'ERRORS.TRANSFER_ATTEMPT'; break; case 'ACCESS_DENIED': error_translate = 'ERRORS.ACCESS_DENIED'; break; - case 'INTERNAL_ERROR:transaction was rejected by daemon': + case 'TX_REJECTED': // if (command === 'request_alias_registration') { // error_translate = 'INFORMER.ALIAS_IN_REGISTER'; // } else { @@ -114,7 +107,6 @@ export class BackendService { error_translate = 'ERRORS.WALLET_WATCH_ONLY_NOT_SUPPORTED'; break; case 'WRONG_PASSWORD': - case 'WRONG_PASSWORD:invalid password': params = JSON.parse(params); if (!params.testEmpty) { error_translate = 'ERRORS.WRONG_PASSWORD'; @@ -163,6 +155,7 @@ export class BackendService { if (error.indexOf('FAILED:failed to open binary wallet file for saving') > -1 && command === 'generate_wallet') { error_translate = ''; } + if (error_translate !== '') { this.modalService.prepareModal('error', error_translate); } diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7a31708b..e093f8bf 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4030,7 +4030,7 @@ void wallet2::send_transaction_to_network(const transaction& tx) bool r = m_core_proxy->call_COMMAND_RPC_SEND_RAW_TX(req, daemon_send_resp); THROW_IF_TRUE_WALLET_EX(!r, error::no_connection_to_daemon, "sendrawtransaction"); THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_BUSY, error::daemon_busy, "sendrawtransaction"); - THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_DISCONNECTED, error::wallet_internal_error, "Transfer attempt while daemon offline"); + THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_DISCONNECTED, error::no_connection_to_daemon, "Transfer attempt while daemon offline"); THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status != API_RETURN_CODE_OK, error::tx_rejected, tx, daemon_send_resp.status); WLT_LOG_L2("transaction " << get_transaction_hash(tx) << " generated ok and sent to daemon:" << ENDL << currency::obj_to_json_str(tx)); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 9aedac42..20b08050 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -43,6 +43,16 @@ #define HTTP_PROXY_TIMEOUT 2000 #define HTTP_PROXY_ATTEMPTS_COUNT 1 +const command_line::arg_descriptor arg_alloc_win_console = { "alloc-win-console", "Allocates debug console with GUI", false }; +const command_line::arg_descriptor arg_html_folder = { "html-path", "Manually set GUI html folder path", "", true }; +const command_line::arg_descriptor arg_xcode_stub = { "-NSDocumentRevisionsDebugMode", "Substitute for xcode bug", "", true }; +const command_line::arg_descriptor arg_enable_gui_debug_mode = { "gui-debug-mode", "Enable debug options in GUI", false, true }; +const command_line::arg_descriptor arg_qt_remote_debugging_port = { "remote-debugging-port", "Specify port for Qt remote debugging", 30333, true }; +const command_line::arg_descriptor arg_remote_node = { "remote-node", "Switch GUI to work with remote node instead of local daemon", "", true }; +const command_line::arg_descriptor arg_enable_qt_logs = { "enable-qt-logs", "Forward Qt log messages into main log", false, true }; +const command_line::arg_descriptor arg_disable_logs_init("disable-logs-init", "Disable log initialization in GUI"); +const command_line::arg_descriptor arg_qt_dev_tools = { "qt-dev-tools", "Enable main web page inspection with Chromium DevTools, [,scale], e.g. \"horizontal,1.3\"", "", false }; + wallets_manager::wallets_manager():m_pview(&m_view_stub), m_stop_singal_sent(false), #ifndef MOBILE_WALLET_BUILD @@ -72,25 +82,6 @@ wallets_manager::wallets_manager():m_pview(&m_view_stub), //m_ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&m_offers_service); } -const command_line::arg_descriptor arg_alloc_win_console = {"alloc-win-console", "Allocates debug console with GUI", false}; -const command_line::arg_descriptor arg_html_folder = {"html-path", "Manually set GUI html folder path", "", true}; -const command_line::arg_descriptor arg_xcode_stub = {"-NSDocumentRevisionsDebugMode", "Substitute for xcode bug", "", true}; -const command_line::arg_descriptor arg_enable_gui_debug_mode = { "gui-debug-mode", "Enable debug options in GUI", false, true }; -const command_line::arg_descriptor arg_qt_remote_debugging_port = { "remote-debugging-port", "Specify port for Qt remote debugging", 30333, true }; -const command_line::arg_descriptor arg_remote_node = { "remote-node", "Switch GUI to work with remote node instead of local daemon", "", true }; -const command_line::arg_descriptor arg_enable_qt_logs = { "enable-qt-logs", "Forward Qt log messages into main log", false, true }; -const command_line::arg_descriptor arg_disable_logs_init("disable-logs-init", "Disable log initialization in GUI"); -const command_line::arg_descriptor arg_qt_dev_tools = { "qt-dev-tools", "Enable main web page inspection with Chromium DevTools, [,scale], e.g. \"horizontal,1.3\"", "", false }; - - -void wallet_lock_time_watching_policy::watch_lock_time(uint64_t lock_time) -{ - if (lock_time > 500) - { - LOG_PRINT_RED_L0("[wallet_lock_time_watching_policy::watch_lock_time] LOCK_TIME: " << lock_time); - } -} - wallets_manager::~wallets_manager() { TRY_ENTRY(); @@ -99,13 +90,60 @@ wallets_manager::~wallets_manager() CATCH_ENTRY_NO_RETURN(); } -void terminate_handler_func() +template +bool wallets_manager::do_exception_safe_call(guarded_code_t guarded_code, error_prefix_maker_t error_prefix_maker, std::string& api_return_code_result) { - LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack - std::fflush(nullptr); // all open output streams are flushed - std::abort(); // default terminate handler's behavior + try + { + api_return_code_result = API_RETURN_CODE_FAIL; // default, should be reset in guarded_code() callback + guarded_code(); + return true; // everything is okay, or at least no exceptions happened + } + catch (const tools::error::not_enough_money& e) + { + LOG_ERROR(error_prefix_maker() << "not enough money: " << e.what()); + api_return_code_result = API_RETURN_CODE_NOT_ENOUGH_MONEY; + } + catch (const tools::error::not_enough_outs_to_mix& e) + { + LOG_ERROR(error_prefix_maker() << "not enough outs to mix: " << e.what()); + api_return_code_result = API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING; + } + catch (const tools::error::tx_too_big& e) + { + LOG_ERROR(error_prefix_maker() << "transaction is too big: " << e.what()); + api_return_code_result = API_RETURN_CODE_TX_IS_TOO_BIG; + } + catch (const tools::error::tx_rejected& e) + { + LOG_ERROR(error_prefix_maker() << "transaction " << get_transaction_hash(e.tx()) << " was rejected by daemon with status " << e.status()); + api_return_code_result = API_RETURN_CODE_TX_REJECTED; + } + catch (const tools::error::daemon_busy& e) + { + LOG_ERROR(error_prefix_maker() << "daemon is busy: " << e.what()); + api_return_code_result = API_RETURN_CODE_BUSY; + } + catch (const tools::error::no_connection_to_daemon& e) + { + LOG_ERROR(error_prefix_maker() << "no connection to daemon: " << e.what()); + api_return_code_result = API_RETURN_CODE_DISCONNECTED; + } + catch (const std::exception& e) + { + LOG_ERROR(error_prefix_maker() << "internal error: " << e.what()); + api_return_code_result = API_RETURN_CODE_INTERNAL_ERROR + std::string(":") + e.what(); + } + catch (...) + { + LOG_ERROR(error_prefix_maker() << "unknown error"); + api_return_code_result = API_RETURN_CODE_INTERNAL_ERROR; + } + + return false; // smth bad happened } + bool wallets_manager::init_command_line(int argc, char* argv[]) { TRY_ENTRY(); @@ -190,7 +228,7 @@ bool wallets_manager::init_command_line(int argc, char* argv[]) ss << "Command line has wrong arguments: " << std::endl; for (int i = 0; i != argc; i++) ss << "[" << i << "] " << argv[i] << std::endl; - std::cerr << ss.str() << std::endl; + std::cerr << ss.str() << std::endl << std::flush; return false; } @@ -201,6 +239,13 @@ bool wallets_manager::init_command_line(int argc, char* argv[]) CATCH_ENTRY2(false); } +void terminate_handler_func() +{ + LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack + std::fflush(nullptr); // all open output streams are flushed + std::abort(); // default terminate handler's behavior +} + bool wallets_manager::init(view::i_view* pview_handler) { m_stop_singal_sent = false; @@ -800,7 +845,7 @@ std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter } catch (const std::exception& e) { - return std::string(API_RETURN_CODE_WRONG_PASSWORD) + ":" + e.what(); + return std::string(API_RETURN_CODE_INTERNAL_ERROR) + ":" + e.what(); } } @@ -1181,6 +1226,7 @@ std::string wallets_manager::get_alias_coast(const std::string& a, uint64_t& coa return rsp.status; } + std::string wallets_manager::request_alias_registration(const currency::alias_rpc_details& al, uint64_t wallet_id, uint64_t fee, currency::transaction& res_tx, uint64_t reward) { currency::extra_alias_entry ai = AUTO_VAL_INIT(ai); @@ -1198,23 +1244,17 @@ std::string wallets_manager::request_alias_registration(const currency::alias_rp if (m_rpc_proxy->call_COMMAND_RPC_GET_ALIAS_DETAILS(req, rsp) && rsp.status == API_RETURN_CODE_NOT_FOUND) { GET_WALLET_BY_ID(wallet_id, w); - try - { - w->get()->request_alias_registration(ai, res_tx, fee, reward); - return API_RETURN_CODE_OK; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "request_alias_registration error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "request_alias_registration error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->request_alias_registration(ai, res_tx, fee, reward); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "request_alias_registration error: "; }, + api_return_code_result + ); + return api_return_code_result; } return API_RETURN_CODE_ALREADY_EXISTS; @@ -1237,23 +1277,17 @@ std::string wallets_manager::request_alias_update(const currency::alias_rpc_deta if (m_rpc_proxy->call_COMMAND_RPC_GET_ALIAS_DETAILS(req, rsp) && rsp.status == API_RETURN_CODE_OK) { GET_WALLET_BY_ID(wallet_id, w); - try - { - w->get()->request_alias_update(ai, res_tx, fee, reward); - return API_RETURN_CODE_OK; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "request_alias_update error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "request_alias_update error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->request_alias_update(ai, res_tx, fee, reward); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "request_alias_update error: "; }, + api_return_code_result + ); + return api_return_code_result; } return API_RETURN_CODE_FILE_NOT_FOUND; @@ -1308,64 +1342,48 @@ std::string wallets_manager::transfer(size_t wallet_id, const view::transfer_par - try - { - //set transaction unlock time if it was specified by user - uint64_t unlock_time = 0; - if (tp.lock_time) - { - if (tp.lock_time > CURRENCY_MAX_BLOCK_NUMBER) - unlock_time = tp.lock_time; - else - unlock_time = w->get()->get_blockchain_current_size() + tp.lock_time; - } + //set transaction unlock time if it was specified by user + uint64_t unlock_time = 0; + if (tp.lock_time) + { + if (tp.lock_time > CURRENCY_MAX_BLOCK_NUMBER) + unlock_time = tp.lock_time; + else + unlock_time = w->get()->get_blockchain_current_size() + tp.lock_time; + } - //process attachments - if (tp.comment.size()) + //process attachments + if (tp.comment.size()) + { + currency::tx_comment tc = AUTO_VAL_INIT(tc); + tc.comment = tp.comment; + extra.push_back(tc); + } + if (tp.push_payer) + { + currency::create_and_add_tx_payer_to_container_from_address(extra, w->get()->get_account().get_keys().account_address, w->get()->get_top_block_height(), w->get()->get_core_runtime_config()); + } + if (!tp.hide_receiver) + { + for (auto& d : dsts) { - currency::tx_comment tc = AUTO_VAL_INIT(tc); - tc.comment = tp.comment; - extra.push_back(tc); + for (auto& a : d.addr) + currency::create_and_add_tx_receiver_to_container_from_address(extra, a, w->get()->get_top_block_height(), w->get()->get_core_runtime_config()); } - if (tp.push_payer) - { - currency::create_and_add_tx_payer_to_container_from_address(extra, w->get()->get_account().get_keys().account_address, w->get()->get_top_block_height(), w->get()->get_core_runtime_config()); - } - if (!tp.hide_receiver) - { - for (auto& d : dsts) - { - for (auto& a : d.addr) - currency::create_and_add_tx_receiver_to_container_from_address(extra, a, w->get()->get_top_block_height(), w->get()->get_core_runtime_config()); - } - } - w->get()->transfer(dsts, tp.mixin_count, unlock_time ? unlock_time + 1 : 0, fee, extra, attachments, res_tx); - } - catch (const tools::error::not_enough_money& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: not enough money: " << e.what()); - return API_RETURN_CODE_NOT_ENOUGH_MONEY; - } - catch (const tools::error::not_enough_outs_to_mix& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: not outs to mix: " << e.what()); - return API_RETURN_CODE_NOT_ENOUGH_OUTPUTS_FOR_MIXING; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "Transfer error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; } - return API_RETURN_CODE_OK; + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->transfer(dsts, tp.mixin_count, unlock_time ? unlock_time + 1 : 0, fee, extra, attachments, res_tx); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "Transfer error: "; }, + api_return_code_result + ); + return api_return_code_result; } bool wallets_manager::get_is_remote_daemon_connected() @@ -1463,100 +1481,89 @@ std::string wallets_manager::create_proposal(const view::create_proposal_param_g { //tools::wallet2::escrow_contracts_container cc; GET_WALLET_OPT_BY_ID(cpp.wallet_id, w); - try - { - currency::transaction tx = AUTO_VAL_INIT(tx); - currency::transaction template_tx = AUTO_VAL_INIT(template_tx); - w.w->get()->send_escrow_proposal(cpp, tx, template_tx); - //TODO: add some - return API_RETURN_CODE_OK; - } - catch (const tools::error::not_enough_money& e) - { - LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: API_RETURN_CODE_NOT_ENOUGH_MONEY: " << e.what()); - std::string err_code = API_RETURN_CODE_NOT_ENOUGH_MONEY; - return err_code; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + currency::transaction tx = AUTO_VAL_INIT(tx); + currency::transaction template_tx = AUTO_VAL_INIT(template_tx); + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w.w->get()->send_escrow_proposal(cpp, tx, template_tx); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: "; }, + api_return_code_result + ); + return api_return_code_result; } std::string wallets_manager::accept_proposal(size_t wallet_id, const crypto::hash& contract_id) { GET_WALLET_OPT_BY_ID(wallet_id, w); - try - { - w.w->get()->accept_proposal(contract_id, TX_DEFAULT_FEE); - //TODO: add some - return API_RETURN_CODE_OK; - } - catch (...) - { - return API_RETURN_CODE_FAIL; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w.w->get()->accept_proposal(contract_id, TX_DEFAULT_FEE); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "accept_proposal error: "; }, + api_return_code_result + ); + return api_return_code_result; } + std::string wallets_manager::release_contract(size_t wallet_id, const crypto::hash& contract_id, const std::string& contract_over_type) { GET_WALLET_OPT_BY_ID(wallet_id, w); - try - { - w.w->get()->finish_contract(contract_id, contract_over_type); - //TODO: add some - return API_RETURN_CODE_OK; - } - catch (...) - { - return API_RETURN_CODE_FAIL; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w.w->get()->finish_contract(contract_id, contract_over_type); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "release_contract error: "; }, + api_return_code_result + ); + return api_return_code_result; } + std::string wallets_manager::request_cancel_contract(size_t wallet_id, const crypto::hash& contract_id, uint64_t fee, uint64_t expiration_period) { GET_WALLET_OPT_BY_ID(wallet_id, w); - try - { - w.w->get()->request_cancel_contract(contract_id, fee, expiration_period); - //TODO: add some - return API_RETURN_CODE_OK; - } - catch (const tools::error::not_enough_money& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "request_cancel_contract error: API_RETURN_CODE_NOT_ENOUGH_MONEY: " << e.what()); - return API_RETURN_CODE_NOT_ENOUGH_MONEY; - } - catch (...) - { - return API_RETURN_CODE_FAIL; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w.w->get()->request_cancel_contract(contract_id, fee, expiration_period); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "request_cancel_contract error: "; }, + api_return_code_result + ); + return api_return_code_result; } + std::string wallets_manager::accept_cancel_contract(size_t wallet_id, const crypto::hash& contract_id) { GET_WALLET_OPT_BY_ID(wallet_id, w); - try - { - TIME_MEASURE_START_MS(timing1); - w.w->get()->accept_cancel_contract(contract_id); - //TODO: add some - TIME_MEASURE_FINISH_MS(timing1); - if (timing1 > 500) - LOG_PRINT_RED_L0(get_wallet_log_prefix(wallet_id) + "[daemon_backend::accept_cancel_contract] LOW PERFORMANCE: " << timing1 ); - return API_RETURN_CODE_OK; - } - catch (...) - { - return API_RETURN_CODE_FAIL; - } + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + TIME_MEASURE_START_MS(timing1); + w.w->get()->accept_cancel_contract(contract_id); + TIME_MEASURE_FINISH_MS(timing1); + if (timing1 > 500) + LOG_PRINT_RED_L0(get_wallet_log_prefix(wallet_id) + "[daemon_backend::accept_cancel_contract] LOW PERFORMANCE: " << timing1); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "accept_cancel_contract error: "; }, + api_return_code_result + ); + return api_return_code_result; } + std::string wallets_manager::backup_wallet(uint64_t wallet_id, const std::wstring& path) { GET_WALLET_OPT_BY_ID(wallet_id, w); @@ -1662,76 +1669,50 @@ std::string wallets_manager::push_offer(size_t wallet_id, const bc_services::off { GET_WALLET_BY_ID(wallet_id, w); - try - { - w->get()->push_offer(od, res_tx); - return API_RETURN_CODE_OK; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "push_offer error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(wallet_id) + "push_offer error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->push_offer(od, res_tx); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(wallet_id) + "push_offer error: "; }, + api_return_code_result + ); + return api_return_code_result; } + std::string wallets_manager::cancel_offer(const view::cancel_offer_param& co, currency::transaction& res_tx) { GET_WALLET_BY_ID(co.wallet_id, w); - try - { - w->get()->cancel_offer_by_id(co.tx_id, co.no, TX_DEFAULT_FEE, res_tx); - return API_RETURN_CODE_OK; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(co.wallet_id) + "cancel_offer error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(co.wallet_id) + "cancel_offer error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->cancel_offer_by_id(co.tx_id, co.no, TX_DEFAULT_FEE, res_tx); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(co.wallet_id) + "cancel_offer error: "; }, + api_return_code_result + ); + return api_return_code_result; } std::string wallets_manager::push_update_offer(const bc_services::update_offer_details& uo, currency::transaction& res_tx) { GET_WALLET_BY_ID(uo.wallet_id, w); - try - { - w->get()->update_offer_by_id(uo.tx_id, uo.no, uo.od, res_tx); - return API_RETURN_CODE_OK; - } - catch (const std::exception& e) - { - LOG_ERROR(get_wallet_log_prefix(uo.wallet_id) + "push_update_offer error: " << e.what()); - std::string err_code = API_RETURN_CODE_INTERNAL_ERROR; - err_code += std::string(":") + e.what(); - return err_code; - } - catch (...) - { - LOG_ERROR(get_wallet_log_prefix(uo.wallet_id) + "push_update_offer error: unknown error"); - return API_RETURN_CODE_INTERNAL_ERROR; - } + std::string api_return_code_result = API_RETURN_CODE_FAIL; + do_exception_safe_call( + [&]() { + w->get()->update_offer_by_id(uo.tx_id, uo.no, uo.od, res_tx); + api_return_code_result = API_RETURN_CODE_OK; + }, + [&]() { return get_wallet_log_prefix(uo.wallet_id) + "push_update_offer error: "; }, + api_return_code_result + ); + return api_return_code_result; } -// std::string daemon_backend::get_all_offers(currency::COMMAND_RPC_GET_OFFERS_EX::response& od) -// { -// currency::COMMAND_RPC_GET_OFFERS_EX::request rq = AUTO_VAL_INIT(rq); -// m_rpc_proxy->call_COMMAND_RPC_GET_OFFERS_EX(rq, od); -// return API_RETURN_CODE_OK; -// } - std::string wallets_manager::get_offers_ex(const bc_services::core_offers_filter& cof, std::list& offers, uint64_t& total_count) { @@ -1968,3 +1949,16 @@ std::string wallets_manager::get_wallet_log_prefix(size_t wallet_id) const return m_wallet_log_prefixes[wallet_id]; } + +// +// wallet_lock_time_watching_policy +// + +void wallet_lock_time_watching_policy::watch_lock_time(uint64_t lock_time) +{ + if (lock_time > 500) + { + LOG_PRINT_RED_L0("[wallet_lock_time_watching_policy::watch_lock_time] LOCK_TIME: " << lock_time); + } +} + diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index 75cd8827..0ed2ff61 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -159,6 +159,7 @@ public: bool is_qt_logs_enabled() const { return m_qt_logs_enbaled; } std::string get_qt_dev_tools_option() const { return m_qt_dev_tools; } void set_use_deffered_global_outputs(bool use) { m_use_deffered_global_outputs = use; } + private: void main_worker(const po::variables_map& vm); bool init_local_daemon(); @@ -172,6 +173,10 @@ private: void init_wallet_entry(wallet_vs_options& wo, uint64_t id); static void prepare_wallet_status_info(wallet_vs_options& wo, view::wallet_status_info& wsi); bool get_is_remote_daemon_connected(); + + template + bool do_exception_safe_call(guarded_code_t guarded_code, error_prefix_maker_t error_prefix_maker, std::string& api_return_code_result); + //----- i_backend_wallet_callback ------ virtual void on_new_block(size_t wallet_id, uint64_t height, const currency::block& block); virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined); @@ -223,8 +228,7 @@ private: std::vector m_wallet_log_prefixes; mutable critical_section m_wallet_log_prefixes_lock; -}; - - + +}; // class wallets_manager