1
0
Fork 0
forked from lthn/blockchain
blockchain/src/wallet/wallets_manager.h
2020-09-01 00:26:46 +02:00

230 lines
11 KiB
C++

// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Boolberry developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <boost/thread/shared_mutex.hpp>
#include <boost/program_options.hpp>
#include "warnings.h"
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
DISABLE_VS_WARNINGS(4503)
#include "include_base_utils.h"
#include "version.h"
using namespace epee;
#include "console_handler.h"
#include "p2p/net_node.h"
#include "currency_core/checkpoints_create.h"
#ifndef MOBILE_WALLET_BUILD
#include "currency_core/currency_core.h"
#include "currency_core/bc_offers_service.h"
#include "rpc/core_rpc_server.h"
#include "currency_protocol/currency_protocol_handler.h"
#include "core_fast_rpc_proxy.h"
#endif
//#include "daemon/daemon_commands_handler.h"
//#include "common/miniupnp_helper.h"
#include "view_iface.h"
#include "wallet2.h"
#include "wallet_id_adapter.h"
#include "wallet_rpc_server.h"
POP_VS_WARNINGS
namespace po = boost::program_options;
#if defined(WIN32)
#include <crtdbg.h>
#endif
struct wallet_lock_time_watching_policy
{
static void watch_lock_time(uint64_t lock_time);
};
class wallets_manager : public i_backend_wallet_callback
{
public:
struct wallet_vs_options
{
currency::core_runtime_config core_conf;
epee::locked_object<std::shared_ptr<tools::wallet2>, wallet_lock_time_watching_policy> w;
std::shared_ptr<tools::wallet_rpc_server> rpc_wrapper; //500 bytes of extra data, we can afford it, to have rpc-like invoke map
std::atomic<bool> do_mining;
std::atomic<bool> major_stop;
std::atomic<bool> stop_for_refresh; //use separate var for passing to "refresh" member function,
//because it can be changed there due to internal interruption logis
std::atomic<bool> break_mining_loop;
std::atomic<uint64_t> wallet_state;
std::atomic<uint64_t> last_wallet_synch_height;
std::atomic<uint64_t>* plast_daemon_height;
std::atomic<uint64_t>* plast_daemon_network_state;
//std::atomic<bool>* plast_daemon_is_disconnected;
std::shared_ptr<const tools::proxy_diagnostic_info> m_pproxy_diagnostig_info;
std::atomic<bool> has_related_alias_in_unconfirmed;
std::atomic<bool> need_to_update_wallet_info;
std::atomic<bool> long_refresh_in_progress;
epee::critical_section long_refresh_in_progress_lock; //secure wallet state and prevent from long wait while long refresh is in work
view::i_view* pview;
uint64_t wallet_id;
epee::locked_object<std::list<bc_services::offer_details_ex>> offers;
std::thread miner_thread;
void worker_func();
void stop(bool wait = true);
std::string get_log_prefix() const { return std::string("[") + epee::string_tools::num_to_string_fast(wallet_id) + ":" + w->get()->get_log_prefix() + "]"; }
~wallet_vs_options();
};
wallets_manager();
~wallets_manager();
bool init_command_line(int argc, char* argv[]);
bool init(view::i_view* pview_handler);
bool start();
bool stop();
bool quick_stop_no_save(); //stop without storing wallets
bool quick_clear_wallets_no_save();
bool send_stop_signal();
bool get_opened_wallets(std::list<view::open_wallet_response>& result);
std::string open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr, bool exclude_mining_txs = false);
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 get_wallet_status(uint64_t wallet_id);
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, bool exclude_mining_txs = false);
std::string get_wallet_info(size_t wallet_id, view::wallet_info& wi);
std::string get_contracts(size_t wallet_id, std::vector<tools::wallet_public::escrow_contract_details>& contracts);
std::string create_proposal(const view::create_proposal_param_gui& cpp);
std::string accept_proposal(size_t wallet_id, const crypto::hash& contract_id);
std::string release_contract(size_t wallet_id, const crypto::hash& contract_id, const std::string& contract_over_type);
std::string request_cancel_contract(size_t wallet_id, const crypto::hash& contract_id, uint64_t fee, uint64_t expiration_period);
std::string accept_cancel_contract(size_t wallet_id, const crypto::hash& contract_id);
std::string get_connectivity_status();
std::string get_wallet_info(wallet_vs_options& w, view::wallet_info& wi);
std::string close_wallet(size_t wallet_id);
std::string push_offer(size_t wallet_id, const bc_services::offer_details_ex& od, currency::transaction& res_tx);
std::string cancel_offer(const view::cancel_offer_param& co, currency::transaction& res_tx);
std::string push_update_offer(const bc_services::update_offer_details& uo, currency::transaction& res_tx);
//std::string get_all_offers(currency::COMMAND_RPC_GET_OFFERS_EX::response& od);
std::string get_offers_ex(const bc_services::core_offers_filter& cof, std::list<bc_services::offer_details_ex>& offers, uint64_t& total_count);
std::string get_aliases(view::alias_set& al_set);
std::string get_alias_info_by_address(const std::string& addr, currency::alias_rpc_details& res_details);
std::string get_alias_info_by_name(const std::string& name, currency::alias_rpc_details& res_details);
std::string request_alias_registration(const currency::alias_rpc_details& al, uint64_t wallet_id, uint64_t fee, currency::transaction& res_tx, uint64_t reward);
std::string request_alias_update(const currency::alias_rpc_details& al, uint64_t wallet_id, uint64_t fee, currency::transaction& res_tx, uint64_t reward);
std::string get_alias_coast(const std::string& a, uint64_t& coast);
std::string validate_address(const std::string& addr, std::string& payment_id);
std::string resync_wallet(uint64_t wallet_id);
std::string start_pos_mining(uint64_t wallet_id);
std::string stop_pos_mining(uint64_t wallet_id);
std::string check_available_sources(uint64_t wallet_id, std::list<uint64_t>& amounts);
std::string get_mining_history(uint64_t wallet_id, tools::wallet_public::mining_history& wrpc);
std::string get_wallet_restore_info(uint64_t wallet_id, std::string& restore_key);
std::string backup_wallet(uint64_t wallet_id, const std::wstring& path);
std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass);
std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass);
std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
std::string get_fav_offers(const std::list<bc_services::offer_id>& hashes, const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res);
uint64_t get_default_fee();
std::string get_mining_estimate(uint64_t amuont_coins,
uint64_t time,
uint64_t& estimate_result,
uint64_t& all_coins_and_pos_diff_rate,
std::vector<uint64_t>& days);
std::string is_pos_allowed();
void toggle_pos_mining();
std::string transfer(size_t wallet_id, const view::transfer_params& tp, currency::transaction& res_tx);
std::string get_config_folder();
std::string is_valid_brain_restore_data(const std::string& seed_phrase);
#ifndef MOBILE_WALLET_BUILD
void subscribe_to_core_events(currency::i_core_event_handler* pevents_handler);
//void unsubscribe_to_core_events();
#endif
void get_gui_options(view::gui_options& opt);
std::string get_wallet_log_prefix(size_t wallet_id) const;
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();
bool deinit_local_daemon();
bool update_state_info();
bool update_wallets();
void loop();
//bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id);
bool get_last_blocks(view::daemon_status_info& dsi);
void update_wallets_info();
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();
//----- 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);
virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/);
virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/);
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti);
std::thread m_main_worker_thread;
std::atomic<bool> m_stop_singal_sent;
std::mutex m_stop_singal_sent_mutex;
std::condition_variable m_stop_singal_sent_mutex_cv;
view::i_view m_view_stub;
view::i_view* m_pview;
std::shared_ptr<tools::i_core_proxy> m_rpc_proxy;
po::variables_map m_vm;
bool m_use_deffered_global_outputs;
std::atomic<uint64_t> m_last_daemon_height;
std::atomic<uint64_t> m_last_daemon_network_state;
std::shared_ptr<const tools::proxy_diagnostic_info> m_pproxy_diganostic_info;
//std::atomic<bool> m_last_daemon_is_disconnected;
// std::atomic<uint64_t> m_last_wallet_synch_height;
std::atomic<uint64_t> m_wallet_id_counter;
std::atomic<bool> m_dont_save_wallet_at_stop;
std::string m_data_dir;
view::gui_options m_ui_opt;
#ifndef MOBILE_WALLET_BUILD
//daemon stuff
bc_services::bc_offers_service m_offers_service;
currency::core m_ccore;
currency::t_currency_protocol_handler<currency::core> m_cprotocol;
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > m_p2psrv;
currency::core_rpc_server m_rpc_server;
#endif
bool m_remote_node_mode;
bool m_qt_logs_enbaled;
std::string m_qt_dev_tools;
std::atomic<bool> m_is_pos_allowed;
std::map<size_t, wallet_vs_options> m_wallets;
//mutable critical_section m_wallets_lock;
mutable boost::shared_mutex m_wallets_lock;
std::vector<std::string> m_wallet_log_prefixes;
mutable critical_section m_wallet_log_prefixes_lock;
};