1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into release

This commit is contained in:
sowle 2020-04-08 23:19:24 +03:00
commit c40fd26c84
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
28 changed files with 321 additions and 337 deletions

View file

@ -224,6 +224,7 @@ namespace net_utils
struct abstract_callback_base
{
virtual bool do_call(const std::string& piece_of_transfer) = 0;
virtual ~abstract_callback_base() {}
};
template <typename callback_t>

View file

@ -907,6 +907,7 @@ using namespace std;
struct idle_handler_base
{
virtual bool do_call(const std::string& piece_of_data, uint64_t total_bytes, uint64_t received_bytes) = 0;
virtual ~idle_handler_base() {}
};
template <typename callback_t>

View file

@ -96,7 +96,6 @@ namespace currency
nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub;
nodetool::i_p2p_endpoint<connection_context>* m_p2p;
std::atomic<uint32_t> m_syncronized_connections_count;
std::atomic<bool> m_synchronized;
std::atomic<bool> m_have_been_synchronized;
std::atomic<uint64_t> m_max_height_seen;

View file

@ -15,7 +15,6 @@ namespace currency
t_currency_protocol_handler<t_core>::t_currency_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout)
: m_core(rcore)
, m_p2p(p_net_layout)
, m_syncronized_connections_count(0)
, m_synchronized(false)
, m_have_been_synchronized(false)
, m_max_height_seen(0)
@ -606,25 +605,19 @@ namespace currency
template<class t_core>
bool t_currency_protocol_handler<t_core>::on_idle()
{
bool have_synced_conn = false;
m_p2p->for_each_connection([&](currency_connection_context& context, nodetool::peerid_type peer_id)->bool{
if (context.m_state == currency_connection_context::state_normal)
{
have_synced_conn = true;
return false;
}
return true;
});
size_t synchronized_connections_count = get_synchronized_connections_count();
size_t total_connections_count = m_p2p->get_connections_count();
bool have_enough_synchronized_connections = synchronized_connections_count > total_connections_count / 2;
if (have_synced_conn && !m_synchronized)
if (have_enough_synchronized_connections && !m_synchronized)
{
on_connection_synchronized();
m_synchronized = true;
LOG_PRINT_MAGENTA("Synchronized set to TRUE (idle)", LOG_LEVEL_0);
LOG_PRINT_MAGENTA("Synchronized set to TRUE (" << synchronized_connections_count << " of " << total_connections_count << " conn. synced)", LOG_LEVEL_0);
}
else if (!have_synced_conn && m_synchronized)
else if (!have_enough_synchronized_connections && m_synchronized)
{
LOG_PRINT_MAGENTA("Synchronized set to FALSE (idle)", LOG_LEVEL_0);
LOG_PRINT_MAGENTA("Synchronized set to FALSE (" << synchronized_connections_count << " of " << total_connections_count << " conn. synced)", LOG_LEVEL_0);
m_synchronized = false;
}

View file

@ -23,8 +23,23 @@ if (!epee::serialization::load_t_from_json(var_name, param.toStdString())) \
return MAKE_RESPONSE(default_ar); \
}
#define PREPARE_RESPONSE(rsp_type, var_name) view::api_response_t<rsp_type> var_name = AUTO_VAL_INIT(var_name);
#define MAKE_RESPONSE(r) epee::serialization::store_t_to_json(r).c_str();
template<typename T>
QString make_response(const T& r)
{
std::string str = epee::serialization::store_t_to_json(r);
return str.c_str();
}
template<typename T>
QString make_response_dbg(const T& r, const std::string& location)
{
std::string str = epee::serialization::store_t_to_json(r);
LOG_PRINT_YELLOW("***** API RESPONSE from " << location << " : " << ENDL << str, LOG_LEVEL_0);
return str.c_str();
}
#define PREPARE_RESPONSE(rsp_type, var_name) view::api_response_t<rsp_type> var_name = AUTO_VAL_INIT(var_name)
#define MAKE_RESPONSE(r) (r.error_code == API_RETURN_CODE_OK || r.error_code == API_RETURN_CODE_TRUE) ? make_response(r) : make_response_dbg(r, LOCATION_STR)
#define LOG_API_TIMING() const char* pfunc_call_name = LOCAL_FUNCTION_DEF__; LOG_PRINT_BLUE("[API:" << pfunc_call_name << "]-->>", LOG_LEVEL_0); uint64_t ticks_before_start = epee::misc_utils::get_tick_count(); \
auto cb_leave = epee::misc_utils::create_scope_leave_handler([&ticks_before_start, &pfunc_call_name](){ \

View file

@ -3556,13 +3556,15 @@ var AppComponent = /** @class */ (function () {
}
var tr_exists = wallet.excluded_history.some(function (elem) { return elem.tx_hash === tr_info.tx_hash; });
tr_exists = (!tr_exists) ? wallet.history.some(function (elem) { return elem.tx_hash === tr_info.tx_hash; }) : tr_exists;
wallet.prepareHistory([tr_info]);
if (wallet.restore) {
wallet.total_history_item = wallet.history.length;
wallet.totalPages = Math.ceil(wallet.total_history_item / _this.variablesService.count);
wallet.totalPages > _this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map(function (value, index) { return value + index; })
: wallet.pages = new Array(wallet.totalPages).fill(1).map(function (value, index) { return value + index; });
if (wallet.currentPage === 1) {
wallet.prepareHistory([tr_info]);
if (wallet.restore) {
wallet.total_history_item = wallet.history.length;
wallet.totalPages = Math.ceil(wallet.total_history_item / _this.variablesService.count);
wallet.totalPages > _this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map(function (value, index) { return value + index; })
: wallet.pages = new Array(wallet.totalPages).fill(1).map(function (value, index) { return value + index; });
}
}
if (tr_info.hasOwnProperty('contract')) {
var exp_med_ts = _this.variablesService.exp_med_ts;
@ -7759,7 +7761,7 @@ var SidebarComponent = /** @class */ (function () {
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<div class=\"chart-header\">\r\n <div class=\"general\">\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE' | translate }}</span>\r\n <span class=\"value\">\r\n <app-staking-switch [wallet_id]=\"variablesService.currentWallet.wallet_id\" [(staking)]=\"variablesService.currentWallet.staking\"></app-staking-switch>\r\n </span>\r\n </div>\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE_PENDING' | translate }}</span>\r\n <span class=\"value\">{{pending.total | intToMoney}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE_TOTAL' | translate }}</span>\r\n <span class=\"value\">{{total | intToMoney}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n </div>\r\n <div class=\"selected\" *ngIf=\"selectedDate && selectedDate.date\">\r\n <span>{{selectedDate.date | date : 'MMM. EEEE, dd, yyyy'}}</span>\r\n <span>{{selectedDate.amount}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n</div>\r\n\r\n<div class=\"chart\">\r\n <div [chart]=\"chart\"></div>\r\n</div>\r\n\r\n<div class=\"chart-options\">\r\n <div class=\"title\">\r\n {{ 'STAKING.TITLE_PERIOD' | translate }}\r\n </div>\r\n <div class=\"options\">\r\n <ng-container *ngFor=\"let period of periods\">\r\n <button type=\"button\" [class.active]=\"period.active\" (click)=\"changePeriod(period)\">{{period.title}}</button>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"title\">\r\n {{ 'STAKING.TITLE_GROUP' | translate }}\r\n </div>\r\n <div class=\"options\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <button type=\"button\" [class.active]=\"group.active\" (click)=\"changeGroup(group)\">{{group.title}}</button>\r\n </ng-container>\r\n </div>\r\n</div>\r\n"
module.exports = "<div class=\"chart-header\">\r\n <div class=\"general\">\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE' | translate }}</span>\r\n <span class=\"value\">\r\n <app-staking-switch [wallet_id]=\"variablesService.currentWallet.wallet_id\" [(staking)]=\"variablesService.currentWallet.staking\"></app-staking-switch>\r\n </span>\r\n </div>\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE_PENDING' | translate }}</span>\r\n <span class=\"value\">{{pending.total | intToMoney}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n <div>\r\n <span class=\"label\">{{ 'STAKING.TITLE_TOTAL' | translate }}</span>\r\n <span class=\"value\">{{total | intToMoney}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n </div>\r\n <div class=\"selected\" *ngIf=\"selectedDate && selectedDate.date\">\r\n <span>{{selectedDate.date | date : 'EEEE, MMMM d, y'}}</span>\r\n <span>{{selectedDate.amount}} {{variablesService.defaultCurrency}}</span>\r\n </div>\r\n</div>\r\n\r\n<div class=\"chart\">\r\n <div [chart]=\"chart\"></div>\r\n</div>\r\n\r\n<div class=\"chart-options\">\r\n <div class=\"title\">\r\n {{ 'STAKING.TITLE_PERIOD' | translate }}\r\n </div>\r\n <div class=\"options\">\r\n <ng-container *ngFor=\"let period of periods\">\r\n <button type=\"button\" [class.active]=\"period.active\" (click)=\"changePeriod(period)\">{{period.title}}</button>\r\n </ng-container>\r\n </div>\r\n\r\n <div class=\"title\">\r\n {{ 'STAKING.TITLE_GROUP' | translate }}\r\n </div>\r\n <div class=\"options\">\r\n <ng-container *ngFor=\"let group of groups\">\r\n <button type=\"button\" [class.active]=\"group.active\" (click)=\"changeGroup(group)\">{{group.title}}</button>\r\n </ng-container>\r\n </div>\r\n</div>\r\n"
/***/ }),
@ -8821,6 +8823,9 @@ var WalletComponent = /** @class */ (function () {
_this.variablesService.currentWallet.restore = false;
_this.variablesService.currentWallet.total_history_item = data.total_history_items;
_this.variablesService.currentWallet.prepareHistory(data.history);
if (_this.variablesService.currentWallet.currentPage === 1 && data.unconfirmed) {
_this.variablesService.currentWallet.prepareHistory(data.unconfirmed);
}
}
});
}

File diff suppressed because one or more lines are too long

View file

@ -265,13 +265,15 @@ export class AppComponent implements OnInit, OnDestroy {
let tr_exists = wallet.excluded_history.some(elem => elem.tx_hash === tr_info.tx_hash);
tr_exists = (!tr_exists) ? wallet.history.some(elem => elem.tx_hash === tr_info.tx_hash) : tr_exists;
wallet.prepareHistory([tr_info]);
if (wallet.restore) {
wallet.total_history_item = wallet.history.length;
wallet.totalPages = Math.ceil( wallet.total_history_item / this.variablesService.count);
wallet.totalPages > this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: wallet.pages = new Array(wallet.totalPages).fill(1).map((value, index) => value + index);
if (wallet.currentPage === 1) {
wallet.prepareHistory([tr_info]);
if (wallet.restore) {
wallet.total_history_item = wallet.history.length;
wallet.totalPages = Math.ceil( wallet.total_history_item / this.variablesService.count);
wallet.totalPages > this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: wallet.pages = new Array(wallet.totalPages).fill(1).map((value, index) => value + index);
}
}
if (tr_info.hasOwnProperty('contract')) {

View file

@ -16,7 +16,7 @@
</div>
</div>
<div class="selected" *ngIf="selectedDate && selectedDate.date">
<span>{{selectedDate.date | date : 'MMM. EEEE, dd, yyyy'}}</span>
<span>{{selectedDate.date | date : 'EEEE, MMMM d, y'}}</span>
<span>{{selectedDate.amount}} {{variablesService.defaultCurrency}}</span>
</div>
</div>

View file

@ -205,6 +205,9 @@ export class WalletComponent implements OnInit, OnDestroy {
this.variablesService.currentWallet.restore = false;
this.variablesService.currentWallet.total_history_item = data.total_history_items;
this.variablesService.currentWallet.prepareHistory(data.history);
if (this.variablesService.currentWallet.currentPage === 1 && data.unconfirmed) {
this.variablesService.currentWallet.prepareHistory(data.unconfirmed);
}
}
});
}

View file

@ -100,7 +100,7 @@ namespace currency
res.current_max_allowed_block_size = m_core.get_blockchain_storage().get_current_comulative_blocksize_limit();
if (!res.outgoing_connections_count)
res.daemon_network_state = COMMAND_RPC_GET_INFO::daemon_network_state_connecting;
else if (res.synchronized_connections_count > total_conn/2 ) /* m_p2p.get_payload_object().is_synchronized()*/
else if (m_p2p.get_payload_object().is_synchronized())
res.daemon_network_state = COMMAND_RPC_GET_INFO::daemon_network_state_online;
else
res.daemon_network_state = COMMAND_RPC_GET_INFO::daemon_network_state_synchronizing;

View file

@ -198,9 +198,9 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), "payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N>");
m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), "Show blockchain height");
m_cmd_binder.set_handler("wallet_bc_height", boost::bind(&simple_wallet::show_wallet_bcheight, this, _1), "Show blockchain height");
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1), "transfer <mixin_count> <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available)");
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1), "transfer <mixin_count> <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available), <payment_id> is an optional HEX-encoded string");
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log <level> - Change current log detalisation level, <level> is a number 0-4");
m_cmd_binder.set_handler("enable_concole_logger", boost::bind(&simple_wallet::enable_concole_logger, this, _1), "Enables console logging");
m_cmd_binder.set_handler("enable_console_logger", boost::bind(&simple_wallet::enable_console_logger, this, _1), "Enables console logging");
m_cmd_binder.set_handler("resync", boost::bind(&simple_wallet::resync_wallet, this, _1), "Causes wallet to reset all transfers and re-synchronize wallet");
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), "Show this help");
m_cmd_binder.set_handler("get_transfer_info", boost::bind(&simple_wallet::get_transfer_info, this, _1), "displays transfer info by key_image or index");
@ -226,16 +226,17 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), "submit_transfer <signed_tx_file> - broadcast signed tx");
}
//----------------------------------------------------------------------------------------------------
simple_wallet::~simple_wallet()
{
}
bool simple_wallet::enable_concole_logger(const std::vector<std::string> &args)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::enable_console_logger(const std::vector<std::string> &args)
{
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_0);
LOG_PRINT_L0("Console logger enabled");
return true;
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::set_log(const std::vector<std::string> &args)
{
if(args.size() != 1)
@ -1141,26 +1142,31 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
local_args.erase(local_args.begin());
std::string payment_id;
currency::payment_id_t payment_id;
if (1 == local_args.size() % 2)
{
payment_id = local_args.back();
std::string payment_id_hex = local_args.back();
local_args.pop_back();
if (!payment_id_hex.empty() && !currency::parse_payment_id_from_hex_str(payment_id_hex, payment_id))
{
fail_msg_writer() << "unable to parse payment id: " << payment_id_hex << ", HEX-encoded string is expected";
return true;
}
}
if (!currency::is_payment_id_size_ok(payment_id))
{
fail_msg_writer() << "payment id is too long: " << payment_id.size() << " bytes, max allowed: " << BC_PAYMENT_ID_SERVICE_SIZE_MAX;
fail_msg_writer() << "decoded payment id is too long: " << payment_id.size() << " bytes, max allowed: " << BC_PAYMENT_ID_SERVICE_SIZE_MAX;
return true;
}
vector<currency::tx_destination_entry> dsts;
for (size_t i = 0; i < local_args.size(); i += 2)
{
std::string embedded_payment_id;
std::string integrated_payment_id;
currency::tx_destination_entry de;
de.addr.resize(1);
if(!(de.addr.size() == 1 && m_wallet->get_transfer_address(local_args[i], de.addr.front(), embedded_payment_id)))
if(!(de.addr.size() == 1 && m_wallet->get_transfer_address(local_args[i], de.addr.front(), integrated_payment_id)))
{
fail_msg_writer() << "wrong address: " << local_args[i];
return true;
@ -1180,14 +1186,14 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
return true;
}
if (embedded_payment_id.size() != 0)
if (integrated_payment_id.size() != 0)
{
if (payment_id.size() != 0)
{
fail_msg_writer() << "address " + local_args[i] + " has embedded payment id \"" + embedded_payment_id + "\" which conflicts with previously set payment id: \"" << payment_id << "\"";
fail_msg_writer() << "address " + local_args[i] + " has integrated payment id " + epee::string_tools::buff_to_hex_nodelimer(integrated_payment_id) + " which conflicts with previously set payment id: " << epee::string_tools::buff_to_hex_nodelimer(payment_id) << "";
return true;
}
payment_id = embedded_payment_id;
payment_id = integrated_payment_id;
}
dsts.push_back(de);

View file

@ -78,7 +78,7 @@ namespace currency
bool viewkey(const std::vector<std::string> &args);
bool save(const std::vector<std::string> &args);
bool set_log(const std::vector<std::string> &args);
bool enable_concole_logger(const std::vector<std::string> &args);
bool enable_console_logger(const std::vector<std::string> &args);
bool integrated_address(const std::vector<std::string> &args);
bool get_tx_key(const std::vector<std::string> &args_);
bool save_watch_only(const std::vector<std::string> &args);

View file

@ -8,6 +8,6 @@
#define PROJECT_REVISION "5"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 81
#define PROJECT_VERSION_BUILD_NO 82
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"

View file

@ -121,7 +121,7 @@ namespace tools
});
}
//------------------------------------------------------------------------------------------------------------------------------
virtual time_t get_last_success_interract_time()
virtual time_t get_last_success_interract_time() override
{
return m_last_success_interract_time;
}

View file

@ -139,7 +139,7 @@ namespace tools
return tools::get_transfer_address(adr_str, addr, payment_id, this);
}
//------------------------------------------------------------------------------------------------------------------------------
virtual time_t get_last_success_interract_time()
virtual time_t get_last_success_interract_time() override
{
return time(nullptr);
}

View file

@ -3,9 +3,8 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/dll.hpp>
#include "plain_wallet_api.h"
#include "plain_wallet_api_impl.h"
#include "plain_wallet_api_defs.h"
#include "currency_core/currency_config.h"
#include "version.h"
#include "string_tools.h"
@ -15,13 +14,9 @@
#include "common/config_encrypt_helper.h"
#define ANDROID_PACKAGE_NAME "com.zano_mobile"
#ifdef IOS_BUILD
#define HOME_FOLDER "Documents"
#elif ANDROID_BUILD
#define HOME_FOLDER "files"
#else
#define HOME_FOLDER "logs"
#endif
#define LOGS_FOLDER "logs"
#define WALLETS_FOLDER_NAME "wallets"
#define APP_CONFIG_FOLDER "app_config"
#define APP_CONFIG_FILENAME "app_cfg.bin"
@ -31,31 +26,37 @@
#define GENERAL_INTERNAL_ERRROR_INSTANCE "GENERAL_INTERNAL_ERROR: WALLET INSTNACE NOT FOUND"
#define GENERAL_INTERNAL_ERRROR_INIT "Failed to intialize library"
//TODO: global object, subject to refactoring
//TODO: global objects, subject to refactoring
wallets_manager gwm;
std::atomic<bool> initialized(false);
std::atomic<uint64_t> gjobs_counter(1);
std::map<uint64_t, std::string> gjobs;
epee::critical_section gjobs_lock;
std::string gconfig_folder;
namespace plain_wallet
{
typedef epee::json_rpc::response<epee::json_rpc::dummy_result, error> error_response;
std::string get_bundle_root_dir()
std::string get_bundle_working_dir()
{
#ifdef WIN32
return boost::dll::program_location().parent_path().string();
#elif IOS_BUILD
char* env = getenv("HOME");
return env ? env : "";
#elif ANDROID_BUILD
/// data/data/com.zano_mobile/files
return "/data/data/" ANDROID_PACKAGE_NAME;
#else
return "";
#endif
return gconfig_folder;
// #ifdef WIN32
// return boost::dll::program_location().parent_path().string();
// #elif IOS_BUILD
// char* env = getenv("HOME");
// return env ? env : "";
// #elif ANDROID_BUILD
// /// data/data/com.zano_mobile/files
// return "/data/data/" ANDROID_PACKAGE_NAME;
// #else
// return "";
// #endif
}
void set_bundle_working_dir(const std::string& dir)
{
gconfig_folder = dir;
}
std::string get_wallets_folder()
@ -63,7 +64,7 @@ namespace plain_wallet
#ifdef WIN32
return "";
#else
std::string path = get_bundle_root_dir() + "/" + HOME_FOLDER + "/" + WALLETS_FOLDER_NAME + "/";
std::string path = get_bundle_working_dir() + "/" + WALLETS_FOLDER_NAME + "/";
return path;
#endif // WIN32
}
@ -73,7 +74,7 @@ namespace plain_wallet
#ifdef WIN32
return "";
#else
std::string path = get_bundle_root_dir() + "/" + HOME_FOLDER + "/" + APP_CONFIG_FOLDER + "/";
std::string path = get_bundle_working_dir() + "/" + APP_CONFIG_FOLDER + "/";
return path;
#endif // WIN32
}
@ -82,8 +83,8 @@ namespace plain_wallet
void initialize_logs(int log_level)
{
std::string log_dir = get_bundle_root_dir();
log_dir += "/" HOME_FOLDER;
std::string log_dir = get_bundle_working_dir();
log_dir += "/" LOGS_FOLDER;
log_space::get_set_need_thread_id(true, true);
log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet");
@ -101,7 +102,7 @@ namespace plain_wallet
return "{}";
}
std::string init(const std::string& ip, const std::string& port, int log_level)
std::string init(const std::string& ip, const std::string& port, const std::string& working_dir, int log_level)
{
if (initialized)
{
@ -110,13 +111,14 @@ namespace plain_wallet
ok_response.result.return_code = API_RETURN_CODE_ALREADY_EXISTS;
return epee::serialization::store_t_to_json(ok_response);
}
set_bundle_working_dir(working_dir);
initialize_logs(log_level);
std::string argss_1 = std::string("--remote-node=") + ip + ":" + port;
std::string argss_2 = std::string("--disable-logs-init");
char * args[4];
args[0] = "stub";
static const char* arg0_stub = "stub";
args[0] = const_cast<char*>(arg0_stub);
args[1] = const_cast<char*>(argss_1.c_str());
args[2] = const_cast<char*>(argss_2.c_str());
args[3] = nullptr;
@ -211,6 +213,10 @@ namespace plain_wallet
return epee::serialization::store_t_to_json(ok_response);
}
std::string get_connectivity_status()
{
return gwm.get_connectivity_status();
}
std::string get_version()
{
@ -371,7 +377,15 @@ namespace plain_wallet
put_result(job_id, res);
};
}
else
else if (method_name == "get_wallet_status")
{
std::string local_params = params;
async_callback = [job_id, local_params, instance_id]()
{
std::string res = get_wallet_status(instance_id);
put_result(job_id, res);
};
}else
{
view::api_response ar = AUTO_VAL_INIT(ar);
ar.error_code = "UNKNOWN METHOD";

View file

@ -10,7 +10,7 @@
namespace plain_wallet
{
typedef int64_t hwallet;
std::string init(const std::string& ip, const std::string& port, int log_level);
std::string init(const std::string& ip, const std::string& port, const std::string& working_dir, int log_level);
std::string set_log_level(int log_level);
std::string get_version();
std::string get_wallet_files();
@ -20,6 +20,7 @@ namespace plain_wallet
std::string generate_random_key(uint64_t lenght);
std::string get_logs_buffer();
std::string truncate_log();
std::string get_connectivity_status();
std::string open(const std::string& path, const std::string& password);
std::string restore(const std::string& seed, const std::string& path, const std::string& password);

View file

@ -1,176 +0,0 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "plain_wallet_api_impl.h"
#include "wallet/wallet_helpers.h"
namespace plain_wallet
{
typedef epee::json_rpc::response<epee::json_rpc::dummy_result, error> error_response;
plain_wallet_api_impl::plain_wallet_api_impl(const std::string& ip, const std::string& port):
m_stop(false),
m_sync_finished(false)
{
m_wallet.reset(new tools::wallet2());
m_wallet->init(ip + ":" + port);
m_rpc_wrapper.reset(new tools::wallet_rpc_server(*m_wallet));
}
plain_wallet_api_impl::~plain_wallet_api_impl()
{
if (m_sync_thread.joinable())
m_sync_thread.join();
}
std::string plain_wallet_api_impl::open(const std::string& path, const std::string& password)
{
error_response err_result = AUTO_VAL_INIT(err_result);
try
{
CRITICAL_REGION_LOCAL(m_wallet_lock);
m_wallet->load(epee::string_encoding::utf8_to_wstring(path), password);
epee::json_rpc::response<open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
m_wallet->get_recent_transfers_history(ok_response.result.recent_history.history, 0, 20, ok_response.result.recent_history.total_history_items);
m_wallet->get_unconfirmed_transfers(ok_response.result.recent_history.history);
tools::get_wallet_info(*m_wallet, ok_response.result.wi);
return epee::serialization::store_t_to_json(ok_response);
}
catch (const tools::error::wallet_load_notice_wallet_restored& e)
{
LOG_ERROR("Wallet initialize was with problems, but still worked : " << e.what());
err_result.error.code = API_RETURN_CODE_FILE_RESTORED;
return epee::serialization::store_t_to_json(err_result);
}
catch (const std::exception& e)
{
LOG_ERROR("Wallet initialize failed: " << e.what());
err_result.error.code = API_RETURN_CODE_FAIL;
return epee::serialization::store_t_to_json(err_result);
}
}
std::string plain_wallet_api_impl::restore(const std::string& seed, const std::string& path, const std::string& password)
{
error_response err_result = AUTO_VAL_INIT(err_result);
try
{
CRITICAL_REGION_LOCAL(m_wallet_lock);
m_wallet->restore(epee::string_encoding::utf8_to_wstring(path), password, seed);
epee::json_rpc::response<open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
tools::get_wallet_info(*m_wallet, ok_response.result.wi);
return epee::serialization::store_t_to_json(ok_response);
}
catch (const tools::error::wallet_load_notice_wallet_restored& e)
{
LOG_ERROR("Wallet initialize was with problems, but still worked : " << e.what());
err_result.error.code = API_RETURN_CODE_FILE_RESTORED;
return epee::serialization::store_t_to_json(err_result);
}
catch (const std::exception& e)
{
LOG_ERROR("Wallet initialize failed: " << e.what());
err_result.error.code = API_RETURN_CODE_FAIL;
return epee::serialization::store_t_to_json(err_result);
}
}
std::string plain_wallet_api_impl::generate(const std::string& path, const std::string& password)
{
error_response err_result = AUTO_VAL_INIT(err_result);
try
{
CRITICAL_REGION_LOCAL(m_wallet_lock);
m_wallet->generate(epee::string_encoding::utf8_to_wstring(path), password);
epee::json_rpc::response<open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
tools::get_wallet_info(*m_wallet, ok_response.result.wi);
return epee::serialization::store_t_to_json(ok_response);
}
catch (const tools::error::wallet_load_notice_wallet_restored& e)
{
LOG_ERROR("Wallet initialize was with problems, but still worked : " << e.what());
err_result.error.code = API_RETURN_CODE_FILE_RESTORED;
return epee::serialization::store_t_to_json(err_result);
}
catch (const std::exception& e)
{
LOG_ERROR("Wallet initialize failed: " << e.what());
err_result.error.code = API_RETURN_CODE_FAIL;
return epee::serialization::store_t_to_json(err_result);
}
}
std::string plain_wallet_api_impl::start_sync_thread()
{
m_sync_thread = std::thread([&]()
{
try
{
CRITICAL_REGION_LOCAL(m_wallet_lock);
m_wallet->refresh(m_stop);
}
catch (const std::exception& e)
{
LOG_ERROR("Wallet refresh failed: " << e.what());
return;
}
m_sync_finished = true;
});
basic_status_response bsr = AUTO_VAL_INIT(bsr);
bsr.status = API_RETURN_CODE_OK;
return epee::serialization::store_t_to_json(bsr);
}
std::string plain_wallet_api_impl::cancel_sync_thread()
{
m_stop = true;
if (m_sync_thread.joinable())
m_sync_thread.join();
basic_status_response bsr = AUTO_VAL_INIT(bsr);
bsr.status = API_RETURN_CODE_OK;
return epee::serialization::store_t_to_json(bsr);
}
std::string plain_wallet_api_impl::get_sync_status()
{
sync_status_response ssr = AUTO_VAL_INIT(ssr);
ssr.finished = m_sync_finished;
ssr.progress = m_wallet->get_sync_progress();
return epee::serialization::store_t_to_json(ssr);
}
std::string plain_wallet_api_impl::sync()
{
basic_status_response bsr = AUTO_VAL_INIT(bsr);
try
{
CRITICAL_REGION_LOCAL(m_wallet_lock);
m_wallet->refresh(m_stop);
bsr.status = API_RETURN_CODE_OK;
return epee::serialization::store_t_to_json(bsr);
}
catch (const std::exception& e)
{
LOG_ERROR("Wallet refresh failed: " << e.what());
bsr.status = API_RETURN_CODE_FAIL;
return epee::serialization::store_t_to_json(bsr);
}
}
std::string plain_wallet_api_impl::invoke(const std::string& params)
{
CRITICAL_REGION_LOCAL(m_wallet_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;
m_rpc_wrapper->handle_http_request_map(query_info, response_info, stub_conn_context, call_found, reference_stub);
return response_info.m_body;
}
}

View file

@ -1,40 +0,0 @@
// Copyright (c) 2014-2020 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <string>
#include "wallet2.h"
#include "wallet_rpc_server.h"
#include "plain_wallet_api_defs.h"
namespace plain_wallet
{
class plain_wallet_api_impl
{
public:
plain_wallet_api_impl(const std::string& ip, const std::string& port);
~plain_wallet_api_impl();
std::string open(const std::string& path, const std::string& password);
std::string restore(const std::string& seed, const std::string& path, const std::string& password);
std::string generate(const std::string& path, const std::string& password);
std::string start_sync_thread();
std::string cancel_sync_thread();
std::string get_sync_status();
std::string sync();
std::string invoke(const std::string& params);
private:
bool get_wallet_info(view::wallet_info& wi);
std::thread m_sync_thread;
epee::critical_section m_wallet_lock;
std::atomic<bool> m_stop;
std::atomic<bool> m_sync_finished;
std::shared_ptr<tools::wallet2> m_wallet;
std::shared_ptr<tools::wallet_rpc_server> m_rpc_wrapper;
};
}

View file

@ -448,6 +448,19 @@ public:
END_KV_SERIALIZE_MAP()
};
struct general_connectivity_info
{
bool is_online;
bool last_daemon_is_disconnected;
uint64_t last_proxy_communicate_timestamp;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(is_online)
KV_SERIALIZE(last_daemon_is_disconnected)
KV_SERIALIZE(last_proxy_communicate_timestamp)
END_KV_SERIALIZE_MAP()
};
struct header_entry
{

View file

@ -614,6 +614,14 @@ namespace tools
// Returns all payments by given id in unspecified order
void get_payments(const std::string& payment_id, std::list<payment_details>& payments, uint64_t min_height = 0) const;
// callback: (const wallet_public::wallet_transfer_info& wti) -> bool, true -- continue, false -- stop
template<typename callback_t>
void enumerate_transfers_history(callback_t cb, bool enumerate_forward) const;
// callback: (const wallet_public::wallet_transfer_info& wti) -> bool, true -- continue, false -- stop
template<typename callback_t>
void enumerate_unconfirmed_transfers(callback_t cb) const;
bool is_watch_only() const { return m_watch_only; }
void sign_transfer(const std::string& tx_sources_blob, std::string& signed_tx_blob, currency::transaction& tx);
void sign_transfer_files(const std::string& tx_sources_file, const std::string& signed_tx_file, currency::transaction& tx);
@ -1143,6 +1151,31 @@ namespace tools
return false;
}
template<typename callback_t>
void wallet2::enumerate_transfers_history(callback_t cb, bool enumerate_forward) const
{
if (enumerate_forward)
{
for(auto it = m_transfer_history.begin(); it != m_transfer_history.end(); ++it)
if (!cb(*it))
break;
}
else
{
for(auto it = m_transfer_history.rbegin(); it != m_transfer_history.rend(); ++it)
if (!cb(*it))
break;
}
}
template<typename callback_t>
void wallet2::enumerate_unconfirmed_transfers(callback_t cb) const
{
for (auto& el : m_unconfirmed_txs)
if (!cb(el.second))
break;
}
} // namespace tools
#if !defined(KEEP_WALLET_LOG_MACROS)

View file

@ -335,10 +335,12 @@ namespace wallet_public
{
std::string tx_hash;
std::string tx_unsigned_hex; // for cold-signing process
uint64_t tx_size;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(tx_hash)
KV_SERIALIZE(tx_unsigned_hex)
KV_SERIALIZE(tx_size)
END_KV_SERIALIZE_MAP()
};
};
@ -869,6 +871,52 @@ namespace wallet_public
};
};
struct COMMAND_RPC_SEARCH_FOR_TRANSACTIONS
{
struct request
{
crypto::hash tx_id;
bool in;
bool out;
//bool pending;
//bool failed;
bool pool;
bool filter_by_height;
uint64_t min_height;
uint64_t max_height;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
KV_SERIALIZE(in)
KV_SERIALIZE(out)
//KV_SERIALIZE(pending)
//KV_SERIALIZE(failed)
KV_SERIALIZE(pool)
KV_SERIALIZE(filter_by_height)
KV_SERIALIZE(min_height)
KV_SERIALIZE(max_height)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::list<wallet_transfer_info> in;
std::list<wallet_transfer_info> out;
//std::list<wallet_transfer_info> pending;
//std::list<wallet_transfer_info> failed;
std::list<wallet_transfer_info> pool;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(in)
KV_SERIALIZE(out)
//KV_SERIALIZE(pending)
//KV_SERIALIZE(failed)
KV_SERIALIZE(pool)
END_KV_SERIALIZE_MAP()
};
};
inline std::string get_escrow_contract_state_name(uint32_t state)
{

View file

@ -74,11 +74,12 @@ namespace tools
return true;
}
bool has_related_alias_in_unconfirmed = false;
LOG_PRINT_L2("wallet RPC idle: scanning tx pool...");
m_wallet.scan_tx_pool(has_related_alias_in_unconfirmed);
if (m_do_mint)
{
bool has_related_alias_in_unconfirmed = false;
LOG_PRINT_L2("wallet RPC idle: scanning tx pool...");
m_wallet.scan_tx_pool(has_related_alias_in_unconfirmed);
LOG_PRINT_L2("wallet RPC idle: trying to do PoS iteration...");
m_wallet.try_mint_pos(miner_address);
}
@ -300,6 +301,7 @@ namespace tools
else
{
res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx));
res.tx_size = get_object_blobsize(tx);
}
return true;
}
@ -577,6 +579,57 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
bool tx_id_specified = req.tx_id != currency::null_hash;
// process confirmed txs
m_wallet.enumerate_transfers_history([&](const wallet_public::wallet_transfer_info& wti) -> bool {
if (tx_id_specified)
{
if (wti.tx_hash != req.tx_id)
return true; // continue
}
if (req.filter_by_height)
{
if (!wti.height) // unconfirmed
return true; // continue
if (wti.height < req.min_height)
{
// no need to scan more
return false; // stop
}
if (wti.height > req.max_height)
{
return true; // continue
}
}
if (wti.is_income && req.in)
res.in.push_back(wti);
if (!wti.is_income && req.out)
res.out.push_back(wti);
return true; // continue
}, false /* enumerate_forward */);
// process unconfirmed txs
if (req.pool)
{
m_wallet.enumerate_unconfirmed_transfers([&](const wallet_public::wallet_transfer_info& wti) -> bool {
if ((wti.is_income && req.in) || (!wti.is_income && req.out))
res.pool.push_back(wti);
return true; // continue
});
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
WALLET_RPC_BEGIN_TRY_ENTRY();

View file

@ -50,7 +50,8 @@ namespace tools
MAP_JON_RPC_WE("sweep_below", on_sweep_below, wallet_public::COMMAND_SWEEP_BELOW)
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER)
MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER)
//contracts API Skipped block by timestamp, height: 94766, block time 1563035089
MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS)
//contracts API
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
MAP_JON_RPC_WE("contracts_get_all", on_contracts_get_all, wallet_public::COMMAND_CONTRACTS_GET_ALL)
@ -79,6 +80,7 @@ namespace tools
bool on_sweep_below(const wallet_public::COMMAND_SWEEP_BELOW::request& req, wallet_public::COMMAND_SWEEP_BELOW::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_sign_transfer(const wallet_public::COMMAND_SIGN_TRANSFER::request& req, wallet_public::COMMAND_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_submit_transfer(const wallet_public::COMMAND_SUBMIT_TRANSFER::request& req, wallet_public::COMMAND_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);

View file

@ -4,6 +4,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "wallets_manager.h"
#include "currency_core/alias_helper.h"
#ifndef MOBILE_WALLET_BUILD
@ -17,19 +18,20 @@
#include "common/db_backend_selector.h"
#include "common/pre_download.h"
#define GET_WALLET_OPT_BY_ID(wallet_id, name) \
CRITICAL_REGION_LOCAL(m_wallets_lock); \
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); \
auto it = m_wallets.find(wallet_id); \
if (it == m_wallets.end()) \
return API_RETURN_CODE_WALLET_WRONG_ID; \
auto& name = it->second;
#define GET_WALLET_BY_ID(wallet_id, name) \
CRITICAL_REGION_LOCAL(m_wallets_lock); \
auto it = m_wallets.find(wallet_id); \
if (it == m_wallets.end()) \
return API_RETURN_CODE_WALLET_WRONG_ID; \
auto& name = it->second.w;
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock); \
auto it = m_wallets.find(wallet_id); \
if (it == m_wallets.end()) \
return API_RETURN_CODE_WALLET_WRONG_ID; \
auto& name = it->second.w;
#define DAEMON_IDLE_UPDATE_TIME_MS 2000
#define HTTP_PROXY_TIMEOUT 2000
@ -330,7 +332,7 @@ bool wallets_manager::init_local_daemon()
if (!command_line::has_arg(m_vm, command_line::arg_no_predownload) || command_line::has_arg(m_vm, command_line::arg_force_predownload))
{
auto last_update = std::chrono::system_clock::now();
bool r = tools::process_predownload(m_vm, [&](uint64_t total_bytes, uint64_t received_bytes){
res = tools::process_predownload(m_vm, [&](uint64_t total_bytes, uint64_t received_bytes){
auto dif = std::chrono::system_clock::now() - last_update;
if (dif > std::chrono::milliseconds(300))
{
@ -343,11 +345,7 @@ bool wallets_manager::init_local_daemon()
return static_cast<bool>(m_stop_singal_sent);
});
/*if (m_stop_singal_sent)
{
dsi.daemon_network_state = currency::COMMAND_RPC_GET_INFO::daemon_network_state_deintializing;
m_pview->update_daemon_status(dsi);
}*/
CHECK_AND_ASSERT_AND_SET_GUI(res, "pre-downloading failed");
}
@ -498,7 +496,7 @@ void wallets_manager::main_worker(const po::variables_map& m_vm)
loop();
CRITICAL_REGION_BEGIN(m_wallets_lock);
SHARED_CRITICAL_REGION_BEGIN(m_wallets_lock);
for (auto& wo : m_wallets)
{
LOG_PRINT_L0("Storing wallet data...");
@ -686,7 +684,7 @@ std::string wallets_manager::get_my_offers(const bc_services::core_offers_filter
if (m_remote_node_mode)
return API_RETURN_CODE_FAIL;
#ifndef MOBILE_WALLET_BUILD
CRITICAL_REGION_LOCAL(m_wallets_lock);
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock);
while (true)
{
try
@ -752,7 +750,6 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
}
std::string return_code = API_RETURN_CODE_OK;
CRITICAL_REGION_LOCAL(m_wallets_lock);
while (true)
{
try
@ -781,7 +778,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
return std::string(API_RETURN_CODE_WRONG_PASSWORD) + ":" + e.what();
}
}
EXCLUSIVE_CRITICAL_REGION_LOCAL(m_wallets_lock);
wallet_vs_options& wo = m_wallets[owr.wallet_id];
**wo.w = w;
get_wallet_info(wo, owr.wi);
@ -799,16 +796,21 @@ std::string wallets_manager::get_recent_transfers(size_t wallet_id, uint64_t off
return API_RETURN_CODE_CORE_BUSY;
}
w->get()->get_unconfirmed_transfers(tr_hist.unconfirmed);
w->get()->get_recent_transfers_history(tr_hist.history, offset, count, tr_hist.total_history_items);
auto fix_tx = [](tools::wallet_public::wallet_transfer_info& wti) -> void {
wti.show_sender = currency::is_showing_sender_addres(wti.tx);
if (!wti.fee && !currency::is_coinbase(wti.tx))
wti.fee = currency::get_tx_fee(wti.tx);
};
//workaround for missed fee
for (auto & he : tr_hist.unconfirmed)
fix_tx(he);
for (auto & he : tr_hist.history)
{
he.show_sender = currency::is_showing_sender_addres(he.tx);
if (!he.fee && !currency::is_coinbase(he.tx))
{
he.fee = currency::get_tx_fee(he.tx);
}
}
fix_tx(he);
return API_RETURN_CODE_OK;
}
@ -832,9 +834,6 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std
}
CRITICAL_REGION_LOCAL(m_wallets_lock);
try
{
w->generate(path, password);
@ -849,6 +848,7 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std
{
return std::string(API_RETURN_CODE_FAIL) + ":" + e.what();
}
EXCLUSIVE_CRITICAL_REGION_LOCAL(m_wallets_lock);
wallet_vs_options& wo = m_wallets[owr.wallet_id];
**wo.w = w;
init_wallet_entry(wo, owr.wallet_id);
@ -920,9 +920,6 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
}
currency::account_base acc;
CRITICAL_REGION_LOCAL(m_wallets_lock);
try
{
w->restore(path, password, restore_key);
@ -937,6 +934,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
{
return std::string(API_RETURN_CODE_FAIL) + ":" + e.what();
}
EXCLUSIVE_CRITICAL_REGION_LOCAL(m_wallets_lock);
wallet_vs_options& wo = m_wallets[owr.wallet_id];
**wo.w = w;
init_wallet_entry(wo, owr.wallet_id);
@ -945,7 +943,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
}
std::string wallets_manager::close_wallet(size_t wallet_id)
{
CRITICAL_REGION_LOCAL(m_wallets_lock);
EXCLUSIVE_CRITICAL_REGION_LOCAL(m_wallets_lock);
auto it = m_wallets.find(wallet_id);
if (it == m_wallets.end())
@ -960,7 +958,6 @@ std::string wallets_manager::close_wallet(size_t wallet_id)
it->second.w->get()->store();
m_wallets.erase(it);
{
CRITICAL_REGION_LOCAL(m_wallet_log_prefixes_lock);
m_wallet_log_prefixes[wallet_id] = std::string("[") + epee::string_tools::num_to_string_fast(wallet_id) + ":CLOSED] ";
@ -1241,6 +1238,15 @@ bool wallets_manager::get_is_remote_daemon_connected()
return true;
}
std::string wallets_manager::get_connectivity_status()
{
view::general_connectivity_info gci = AUTO_VAL_INIT(gci);
gci.is_online = get_is_remote_daemon_connected();
gci.last_daemon_is_disconnected = m_last_daemon_is_disconnected;
gci.last_proxy_communicate_timestamp = m_rpc_proxy->get_last_success_interract_time();
return epee::serialization::store_t_to_json(gci);
}
std::string wallets_manager::get_wallet_status(uint64_t wallet_id)
{
GET_WALLET_OPT_BY_ID(wallet_id, wo);
@ -1636,7 +1642,7 @@ void wallets_manager::on_transfer_canceled(size_t wallet_id, const tools::wallet
view::transfer_event_info tei = AUTO_VAL_INIT(tei);
tei.ti = wti;
CRITICAL_REGION_LOCAL(m_wallets_lock);
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock);
auto& w = m_wallets[wallet_id].w;
if (w->get() != nullptr)
{

View file

@ -6,6 +6,7 @@
#pragma once
#include <boost/thread/shared_mutex.hpp>
#include <boost/program_options.hpp>
#include "warnings.h"
PUSH_VS_WARNINGS
@ -105,6 +106,7 @@ public:
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);
@ -175,7 +177,6 @@ private:
view::i_view m_view_stub;
view::i_view* m_pview;
std::shared_ptr<tools::i_core_proxy> m_rpc_proxy;
mutable critical_section m_wallets_lock;
po::variables_map m_vm;
std::atomic<uint64_t> m_last_daemon_height;
@ -202,6 +203,9 @@ private:
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;
};

View file

@ -2,6 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/dll.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
@ -30,7 +31,7 @@ struct try_pull_result_open_response
void run_plain_wallet_api_test()
{
LOG_PRINT_L0("Creating instance...");
std::string s = plain_wallet::init("195.201.107.230", "11211", 1);
std::string s = plain_wallet::init("195.201.107.230", "11211", boost::dll::program_location().parent_path().string(), 1);
std::string key = plain_wallet::generate_random_key(10);
std::string test_data = "1234567890 test test ";