From c6dd8b1153b8f66aa82d6d32368d33677948cc58 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 11 Feb 2020 01:14:28 +0100 Subject: [PATCH] massive changes to wallets_manager --- src/wallet/plain_wallet_api.cpp | 201 ++++++++++++++++++++------------ src/wallet/plain_wallet_api.h | 1 + src/wallet/view_iface.h | 2 + src/wallet/wallets_manager.cpp | 25 +++- src/wallet/wallets_manager.h | 7 +- 5 files changed, 158 insertions(+), 78 deletions(-) diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 6cbde104..f575b508 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -8,36 +8,39 @@ #include "currency_core/currency_config.h" #include "version.h" #include "currency_core/currency_format_utils.h" -//#include "wallets_manager.h" +#include "wallets_manager.h" //TODO: global objects, need refactoring. Just temporary solution -std::map ginstances; -epee::critical_section ginstances_lock; -std::atomic gcounter(1); - std::atomic glogs_initialized(false); +// std::map ginstances; +// epee::critical_section ginstances_lock; +// std::atomic gcounter(1); +// std::atomic glogs_initialized(false); #define HOME_FOLDER "Documents" #define WALLETS_FOLDER_NAME "wallets" #define GENERAL_INTERNAL_ERRROR_INSTANCE "GENERAL_INTERNAL_ERROR: WALLET INSTNACE NOT FOUND" - -#define GET_INSTANCE(var_name, instance_handle) plain_wallet_api_impl* var_name = nullptr;\ - CRITICAL_REGION_BEGIN(ginstances_lock);\ - auto it = ginstances.find(instance_handle);\ - if (it == ginstances.end())\ - {\ - LOG_ERROR("Internall error: attempt to get instance wallet with wrong id: " << instance_handle);\ - return GENERAL_INTERNAL_ERRROR_INSTANCE;\ - }\ - var_name = it->second;\ - CRITICAL_REGION_END(); +#define GENERAL_INTERNAL_ERRROR_INIT "Failed to intialize library" +// +// #define GET_INSTANCE(var_name, instance_handle) plain_wallet_api_impl* var_name = nullptr;\ +// CRITICAL_REGION_BEGIN(ginstances_lock);\ +// auto it = ginstances.find(instance_handle);\ +// if (it == ginstances.end())\ +// {\ +// LOG_ERROR("Internall error: attempt to get instance wallet with wrong id: " << instance_handle);\ +// return GENERAL_INTERNAL_ERRROR_INSTANCE;\ +// }\ +// var_name = it->second;\ +// CRITICAL_REGION_END(); //TODO: global object, subject to refactoring -//wallets_manager gwm; +wallets_manager gwm; namespace plain_wallet { + typedef epee::json_rpc::response error_response; + std::string get_bundle_root_dir() { char buffer[1000] = {0}; @@ -48,8 +51,6 @@ namespace plain_wallet std::string get_wallets_folder() { std::string path = get_bundle_root_dir() + "/" + HOME_FOLDER + "/" + WALLETS_FOLDER_NAME; - boost::system::error_code ec; - boost::filesystem::create_directories(path, ec); return path; } @@ -58,6 +59,31 @@ namespace plain_wallet return currency::print_money(amount); } + std::string init(const std::string& ip, const std::string& port) + { + initialize_logs(); + std::string argss_1 = std::string("--remote-nodes=") + ip + ":" + port; + const char * args[] = {"", 0}; + args[1] = argss_1.c_str(); + if (!gwm.init(2, args, nullptr)) + { + LOG_ERROR("Failed to init wallets_manager"); + return GENERAL_INTERNAL_ERRROR_INIT; + } + + if(!gwm.start()) + { + LOG_ERROR("Failed to start wallets_manager"); + return GENERAL_INTERNAL_ERRROR_INIT; + } + + std::string wallet_folder = get_wallets_folder(); + boost::system::error_code ec; + boost::filesystem::create_directories(wallet_folder, ec); + + return API_RETURN_CODE_OK; + } + void initialize_logs() { std::string log_dir = get_bundle_root_dir(); @@ -67,7 +93,7 @@ namespace plain_wallet epee::log_space::log_singletone::add_logger(LOGGER_FILE, "plain_wallet.log", log_dir.c_str()); LOG_PRINT_L0("Plain wallet initialized: " << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ", log location: " << log_dir + "/plain_wallet.log"); - glogs_initialized = true; + //glogs_initialized = true; } std::string get_version() @@ -95,72 +121,101 @@ namespace plain_wallet hwallet create_instance(const std::string& ip, const std::string& port) { - if (!glogs_initialized) - initialize_logs(); - plain_wallet_api_impl* ptr = new plain_wallet_api_impl(ip, port); - hwallet new_h = gcounter++; - CRITICAL_REGION_BEGIN(ginstances_lock); - ginstances[new_h] = ptr; - CRITICAL_REGION_END(); - return new_h; +// plain_wallet_api_impl* ptr = new plain_wallet_api_impl(ip, port); +// hwallet new_h = gcounter++; +// CRITICAL_REGION_BEGIN(ginstances_lock); +// ginstances[new_h] = ptr; +// CRITICAL_REGION_END(); +// return new_h; } void destroy_instance(hwallet h) { - plain_wallet_api_impl* instance_ptr = nullptr; - CRITICAL_REGION_BEGIN(ginstances_lock); - auto it = ginstances.find(h); - if (it == ginstances.end()) +// plain_wallet_api_impl* instance_ptr = nullptr; +// CRITICAL_REGION_BEGIN(ginstances_lock); +// auto it = ginstances.find(h); +// if (it == ginstances.end()) +// { +// LOG_ERROR("Internal error: attempt to delete wallet with wrong instance id: " << h); +// } +// instance_ptr = it->second; +// ginstances.erase(it); +// CRITICAL_REGION_END(); +// delete instance_ptr; + } + std::string open(const std::string& path, const std::string& password) + { + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + std::string rsp = gwm.open_wallet(epee::string_encoding::convert_to_unicode(path), password, 20, ok_response.result); + if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED) { - LOG_ERROR("Internall error: attempt to delete wallet with wrong instance id: " << h); + if (rsp == API_RETURN_CODE_FILE_RESTORED) + { + ok_response.result.recovered = true; + } + return epee::serialization::store_t_to_json(ok_response); } - instance_ptr = it->second; - ginstances.erase(it); - CRITICAL_REGION_END(); - delete instance_ptr; + error_response err_result = AUTO_VAL_INIT(err_result); + err_result.error.code = rsp; + return epee::serialization::store_t_to_json(err_result); } - std::string open(hwallet h, const std::string& path, const std::string& password) + std::string restore(const std::string& seed, const std::string& path, const std::string& password) { - GET_INSTANCE(pimpl, h); - std::string full_path = get_wallets_folder() + "/" + path; - return pimpl->open(full_path, password); - } - std::string restore(hwallet h, const std::string& seed, const std::string& path, const std::string& password) - { - GET_INSTANCE(pimpl, h); - std::string full_path = get_wallets_folder() + "/" + path; - return pimpl->restore(seed, full_path, password); + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + std::string rsp = gwm.restore_wallet(epee::string_encoding::convert_to_unicode(path), password, seed, ok_response.result); + if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED) + { + if (rsp == API_RETURN_CODE_FILE_RESTORED) + { + ok_response.result.recovered = true; + } + return epee::serialization::store_t_to_json(ok_response); + } + error_response err_result = AUTO_VAL_INIT(err_result); + err_result.error.code = rsp; + return epee::serialization::store_t_to_json(err_result); } + std::string generate(hwallet h, const std::string& path, const std::string& password) { - GET_INSTANCE(pimpl, h); - std::string full_path = get_wallets_folder() + "/" + path; - return pimpl->generate(full_path, password); - } - std::string start_sync_thread(hwallet h) - { - GET_INSTANCE(pimpl, h); - pimpl->start_sync_thread(); - return ""; - } - std::string get_sync_status(hwallet h) - { - GET_INSTANCE(pimpl, h); - return pimpl->get_sync_status(); - } - - std::string cancel_sync_thread(hwallet h) - { - GET_INSTANCE(pimpl, h); - return pimpl->cancel_sync_thread(); - } - - std::string sync(hwallet h) - { - GET_INSTANCE(pimpl, h); - return pimpl->sync(); + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + std::string rsp = gwm.generate_wallet(epee::string_encoding::convert_to_unicode(path), password, ok_response.result); + if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED) + { + if (rsp == API_RETURN_CODE_FILE_RESTORED) + { + ok_response.result.recovered = true; + } + return epee::serialization::store_t_to_json(ok_response); + } + error_response err_result = AUTO_VAL_INIT(err_result); + err_result.error.code = rsp; + return epee::serialization::store_t_to_json(err_result); } +// std::string start_sync_thread(hwallet h) +// { +// GET_INSTANCE(pimpl, h); +// pimpl->start_sync_thread(); +// return ""; +// } +// std::string get_sync_status(hwallet h) +// { +// GET_INSTANCE(pimpl, h); +// return pimpl->get_sync_status(); +// } +// +// std::string cancel_sync_thread(hwallet h) +// { +// GET_INSTANCE(pimpl, h); +// return pimpl->cancel_sync_thread(); +// } +// +// std::string sync(hwallet h) +// { +// GET_INSTANCE(pimpl, h); +// return pimpl->sync(); +// } std::string invoke(hwallet h, const std::string& params) { GET_INSTANCE(pimpl, h); diff --git a/src/wallet/plain_wallet_api.h b/src/wallet/plain_wallet_api.h index 42e70362..28701596 100644 --- a/src/wallet/plain_wallet_api.h +++ b/src/wallet/plain_wallet_api.h @@ -12,6 +12,7 @@ namespace plain_wallet typedef int64_t hwallet; hwallet create_instance(const std::string& ip, const std::string& port); void destroy_instance(hwallet h); + std::string init(const std::string& ip, const std::string& port); std::string get_version(); std::string get_wallet_files(); std::string print_money(int64_t); diff --git a/src/wallet/view_iface.h b/src/wallet/view_iface.h index 2b814adc..a15b5713 100644 --- a/src/wallet/view_iface.h +++ b/src/wallet/view_iface.h @@ -424,11 +424,13 @@ public: uint64_t wallet_id; transfers_array recent_history; wallet_info wi; + bool recovered; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(wallet_id) KV_SERIALIZE(recent_history) KV_SERIALIZE(wi) + KV_SERIALIZE(recovered) END_KV_SERIALIZE_MAP() }; diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 30b16176..479d7758 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -10,7 +10,8 @@ #include "string_coding.h" #include "currency_core/core_tools.h" #include "common/callstack_helper.h" -#include "wallet/wallet_helpers.h" +#include "wallet_helpers.h" +#include "core_default_rpc_proxy.h" #define GET_WALLET_OPT_BY_ID(wallet_id, name) \ CRITICAL_REGION_LOCAL(m_wallets_lock); \ @@ -76,7 +77,7 @@ void terminate_handler_func() std::abort(); // default terminate handler's behavior } -bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) +bool wallets_manager::init(int argc, const char* argv[], view::i_view* pview_handler) { m_stop_singal_sent = false; if (pview_handler) @@ -218,7 +219,8 @@ bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) if (command_line::has_arg(m_vm, arg_remote_node)) { - // configure for remote node + m_rpc_proxy.reset(new tools::default_http_core_proxy()); + m_rpc_proxy->set_connection_addr(command_line::get_arg(m_vm, arg_remote_node)); } m_qt_logs_enbaled = command_line::get_arg(m_vm, arg_enable_qt_logs); @@ -565,6 +567,7 @@ void wallets_manager::init_wallet_entry(wallet_vs_options& wo, uint64_t id) wo.plast_daemon_is_disconnected = &m_last_daemon_is_disconnected; wo.pview = m_pview; wo.has_related_alias_in_unconfirmed = false; + wo.rpc_wrapper.reset(new tools::wallet_rpc_server(*wo.w.unlocked_get().get())); if (m_remote_node_mode) wo.core_conf = currency::get_default_core_runtime_config(); else @@ -1128,6 +1131,22 @@ std::string wallets_manager::transfer(size_t wallet_id, const view::transfer_par return API_RETURN_CODE_OK; } +std::string wallets_manager::invoke(uint64_t wallet_id, std::string params) +{ + GET_WALLET_OPT_BY_ID(wallet_id, wo); + auto locker_object = wo.w.lock(); + + epee::net_utils::http::http_request_info query_info = AUTO_VAL_INIT(query_info); + epee::net_utils::http::http_response_info response_info = AUTO_VAL_INIT(response_info); + epee::net_utils::connection_context_base stub_conn_context = AUTO_VAL_INIT(stub_conn_context); + std::string reference_stub; + bool call_found = false; + query_info.m_URI = "/json_rpc"; + query_info.m_body = params; + wo.rpc_wrapper->handle_http_request_map(query_info, response_info, stub_conn_context, call_found, reference_stub); + return response_info.m_body; +} + std::string wallets_manager::get_wallet_info(size_t wallet_id, view::wallet_info& wi) { GET_WALLET_OPT_BY_ID(wallet_id, w); diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index d3d39c7a..e2dc1cef 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -27,8 +27,9 @@ using namespace epee; //#include "common/miniupnp_helper.h" #include "view_iface.h" #include "core_fast_rpc_proxy.h" -#include "wallet/wallet2.h" +#include "wallet2.h" #include "wallet_id_adapter.h" +#include "wallet_rpc_server.h" POP_VS_WARNINGS @@ -55,6 +56,7 @@ public: { currency::core_runtime_config core_conf; epee::locked_object, wallet_lock_time_watching_policy> w; + std::shared_ptr rpc_wrapper; //500 bytes of extra data, we can afford it, to have rpc-like invoke map std::atomic do_mining; std::atomic major_stop; std::atomic stop_for_refresh; //use separate var for passing to "refresh" member function, @@ -80,13 +82,14 @@ public: wallets_manager(); ~wallets_manager(); - bool init(int argc, char* argv[], view::i_view* pview_handler); + bool init(int argc, const char* argv[], view::i_view* pview_handler); bool start(); bool stop(); bool send_stop_signal(); std::string open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr); std::string generate_wallet(const std::wstring& path, const std::string& password, view::open_wallet_response& owr); std::string restore_wallet(const std::wstring& path, const std::string& password, const std::string& restore_key, view::open_wallet_response& owr); + std::string invoke(uint64_t wallet_id, std::string params); std::string run_wallet(uint64_t wallet_id); std::string get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist); std::string get_wallet_info(size_t wallet_id, view::wallet_info& wi);