diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 807d2a16b..a044fab81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -196,6 +196,9 @@ if(BUILD_GUI) find_package(Qt5PrintSupport REQUIRED) target_link_libraries(Zano wallet rpc currency_core crypto common zlibstatic ethash Qt5::WebEngineWidgets Qt5::PrintSupport ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) + if (UNIX AND NOT APPLE) + target_link_libraries(Zano rt) + endif() if(APPLE) target_link_libraries(Zano ${COCOA_LIBRARY}) diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index 92a59b61b..6595763f5 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -28,6 +28,7 @@ namespace command_line const arg_descriptor arg_show_rpc_autodoc = { "show_rpc_autodoc", "Display rpc auto-generated documentation template" }; const arg_descriptor arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true }; + const arg_descriptor arg_disable_ntp = { "disable-ntp", "Disable NTP, could enhance to time synchronization issue but increase network privacy, consider using disable-stop-if-time-out-of-sync with it", false, true }; const arg_descriptor arg_disable_stop_if_time_out_of_sync = { "disable-stop-if-time-out-of-sync", "Do not stop the daemon if serious time synchronization problem is detected", false, true }; const arg_descriptor arg_disable_stop_on_low_free_space = { "disable-stop-on-low-free-space", "Do not stop the daemon if free space at data dir is critically low", false, true }; @@ -39,4 +40,6 @@ namespace command_line const arg_descriptor arg_validate_predownload = { "validate-predownload", "Paranoid mode, re-validate each block from pre-downloaded database and rebuild own database", }; const arg_descriptor arg_predownload_link = { "predownload-link", "Override url for blockchain database pre-downloading", "", true }; + const arg_descriptor arg_deeplink = { "deeplink-params", "Deeplink parameter, in that case app just forward params to running app", "", true }; + } diff --git a/src/common/command_line.h b/src/common/command_line.h index ee7985cce..652d17777 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -216,6 +216,7 @@ namespace command_line extern const arg_descriptor arg_show_details; extern const arg_descriptor arg_show_rpc_autodoc; extern const arg_descriptor arg_disable_upnp; + extern const arg_descriptor arg_disable_ntp; extern const arg_descriptor arg_disable_stop_if_time_out_of_sync; extern const arg_descriptor arg_disable_stop_on_low_free_space; extern const arg_descriptor arg_enable_offers_service; @@ -224,4 +225,5 @@ namespace command_line extern const arg_descriptor arg_force_predownload; extern const arg_descriptor arg_validate_predownload; extern const arg_descriptor arg_predownload_link; + extern const arg_descriptor arg_deeplink; } diff --git a/src/common/db_abstract_accessor.h b/src/common/db_abstract_accessor.h index 71be14f30..77a5dfdde 100644 --- a/src/common/db_abstract_accessor.h +++ b/src/common/db_abstract_accessor.h @@ -600,6 +600,8 @@ namespace tools bdb.get_backend()->enumerate(m_h, &local_enum_handler); } + // callback format: bool cb(uint64_t index, const key_t& key, const value_t& value) + // cb should return true to continue, false -- to stop enumeration template void enumerate_items(t_cb cb)const { diff --git a/src/common/pre_download.h b/src/common/pre_download.h index 5feec36b7..b6d4a74d7 100644 --- a/src/common/pre_download.h +++ b/src/common/pre_download.h @@ -21,8 +21,8 @@ namespace tools }; #ifndef TESTNET - static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1161000.pak", "26660ffcdaf80a43a586e64a1a6da042dcb9ff3b58e14ce1ec9a775b995dc146", 1330022593, 2684313600 }; - static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1161000.pak", "9dd03f08dea396fe32e6483a8221b292be35fa41c29748f119f11c3275956cdc", 1787475468, 2600247296 }; + static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1480000.pak", "2b664de02450cc0082efb6c75824d33ffe694b9b17b21fc7966bcb9be9ac31f7", 1570460883, 3221176320 }; + static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1480000.pak", "67770faa7db22dfe97982611d7471ba5673145589e81e02ed99832644ae328f6", 2042582638, 2968252416 }; #else static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 }; static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 }; diff --git a/src/common/threads_pool.h b/src/common/threads_pool.h new file mode 100644 index 000000000..4e4e3905a --- /dev/null +++ b/src/common/threads_pool.h @@ -0,0 +1,153 @@ +// Copyright (c) 2014-2019 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 +#include +#include + +namespace utils +{ + + struct call_executor_base + { + virtual void execute() = 0; + }; + + template + struct call_executor_t : public call_executor_base + { + call_executor_t(t_executor_func f) :m_func(f) + {} + t_executor_func m_func; + virtual void execute() + { + m_func(); + } + }; + + template + std::shared_ptr build_call_executor(t_executor_func func) + { + std::shared_ptr res(static_cast(new call_executor_t(func))); + return res; + } + + class threads_pool + { + public: + typedef std::list> jobs_container; + + template + static void add_job_to_container(jobs_container& cntr, t_executor_func func) + { + cntr.push_back(std::shared_ptr(static_cast(new call_executor_t(func)))); + } + + void init() + { + int num_threads = std::thread::hardware_concurrency(); + this->init(num_threads); + } + void init(unsigned int num_threads) + { + m_is_stop = false; + + for (int i = 0; i < num_threads; i++) + { + m_threads.push_back(std::thread([this]() {this->worker_func(); })); + } + } + + threads_pool() : m_is_stop(false), m_threads_counter(0) + {} + + template + bool add_job(t_executor_func func) + { + { + std::unique_lock lock(m_queue_mutex); + m_jobs_que.push_back(build_call_executor(func)); + } + m_condition.notify_one(); + return true; + } + + void add_batch_and_wait(const jobs_container& cntr) + { + std::condition_variable batch_condition; + std::mutex batch_mutex; + + + std::atomic cnt = 0; + for (const auto& jb : cntr) + { + call_executor_base* pjob = jb.get(); + add_job([&, pjob]() { + pjob->execute(); + { + std::lock_guard lock(batch_mutex); + cnt++; + } + batch_condition.notify_one(); + }); + } + + std::unique_lock lock(batch_mutex); + batch_condition.wait(lock, [&]() + { + return cnt == cntr.size(); + }); + LOG_PRINT_L0("All jobs finiahed"); + } + + ~threads_pool() + { + m_is_stop = true; + m_condition.notify_all(); + for (auto& th : m_threads) + { + th.join(); + } + } + + private: + void worker_func() + { + LOG_PRINT_L0("Worker thread is started"); + while (true) + { + std::shared_ptr job; + { + std::unique_lock lock(m_queue_mutex); + + m_condition.wait(lock, [this]() + { + return !m_jobs_que.empty() || m_is_stop; + }); + if (m_is_stop) + { + LOG_PRINT_L0("Worker thread is finished"); + return; + } + + job = m_jobs_que.front(); + m_jobs_que.pop_front(); + } + + job->execute(); + } + } + + + + jobs_container m_jobs_que; + std::condition_variable m_condition; + std::mutex m_queue_mutex; + std::vector m_threads; + std::atomic m_is_stop; + std::atomic m_threads_counter; + }; +} \ No newline at end of file diff --git a/src/connectivity_tool/conn_tool.cpp b/src/connectivity_tool/conn_tool.cpp index b14125ad8..d1f2115b9 100644 --- a/src/connectivity_tool/conn_tool.cpp +++ b/src/connectivity_tool/conn_tool.cpp @@ -12,6 +12,7 @@ using namespace epee; #include +//#include #include "p2p/p2p_protocol_defs.h" #include "common/command_line.h" #include "currency_core/currency_core.h" @@ -62,6 +63,7 @@ namespace const command_line::arg_descriptor arg_pack_file = {"pack-file", "perform gzip-packing and calculate hash for a given file", "", true }; const command_line::arg_descriptor arg_unpack_file = {"unpack-file", "Perform gzip-unpacking and calculate hash for a given file", "", true }; const command_line::arg_descriptor arg_target_file = {"target-file", "Specify target file for pack-file and unpack-file commands", "", true }; + //const command_line::arg_descriptor arg_send_ipc = {"send-ipc", "Send IPC request to UI", "", true }; } typedef COMMAND_REQUEST_STAT_INFO_T::stat_info> COMMAND_REQUEST_STAT_INFO; @@ -1165,6 +1167,34 @@ bool process_archive(archive_processor_t& arch_processor, bool is_packing, std:: return true; } +/* +bool handle_send_ipc(const std::string& parms) +{ + try{ + boost::interprocess::message_queue mq + (boost::interprocess::open_only //only open + , GUI_IPC_MESSAGE_CHANNEL_NAME //name + ); + + mq.send(parms.data(), parms.size(), 0); + + return true; + } + catch (const std::exception& ex) + { + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + LOG_ERROR("Failed to receive IPC que: " << ex.what()); + } + + catch (...) + { + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + LOG_ERROR("Failed to receive IPC que: unknown exception"); + } + return false; +} +*/ + bool handle_pack_file(po::variables_map& vm) { bool do_pack = false; @@ -1263,6 +1293,8 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_pack_file); command_line::add_arg(desc_params, arg_unpack_file); command_line::add_arg(desc_params, arg_target_file); + //command_line::add_arg(desc_params, arg_send_ipc); + po::options_description desc_all; desc_all.add(desc_general).add(desc_params); @@ -1339,6 +1371,10 @@ int main(int argc, char* argv[]) { return handle_pack_file(vm) ? EXIT_SUCCESS : EXIT_FAILURE; } + /*else if (command_line::has_arg(vm, arg_send_ipc)) + { + handle_send_ipc(command_line::get_arg(vm, arg_send_ipc)) ? EXIT_SUCCESS : EXIT_FAILURE; + }*/ else { std::cerr << "Not enough arguments." << ENDL; diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index caf20a071..1233da478 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -325,7 +325,7 @@ return 0 if f is in {0,2,4,...,q-1} |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ -static int fe_isnegative(const fe f) { +int fe_isnegative(const fe f) { unsigned char s[32]; fe_tobytes(s, f); return s[0] & 1; @@ -342,16 +342,6 @@ int fe_isnonzero(const fe f) { s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; } -int fe_cmp(const fe a, const fe b) -{ - for (size_t i = 9; i != SIZE_MAX; --i) - { - if ((const uint32_t)a[i] < (const uint32_t)b[i]) return -1; - if ((const uint32_t)a[i] > (const uint32_t)b[i]) return 1; - } - return 0; -} - /* From fe_mul.c */ /* @@ -970,7 +960,7 @@ Can overlap h with f or g. |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */ -static void fe_sub(fe h, const fe f, const fe g) { +void fe_sub(fe h, const fe f, const fe g) { int32_t f0 = f[0]; int32_t f1 = f[1]; int32_t f2 = f[2]; @@ -4310,3 +4300,17 @@ void ge_scalarmult_vartime_p3_v2(ge_p3 *r, const unsigned char *a, const ge_p3 * ge_p1p1_to_p3(r, &t); } } + + +void ge_cached_to_p2(ge_p2 *r, const ge_cached *c) +{ + static const fe inv2 = { 10, 0, 0, 0, 0, 0, 0, 0, 0, -16777216 }; + + fe_sub(r->X, c->YplusX, c->YminusX); + fe_mul(r->X, r->X, inv2); + + fe_add(r->Y, c->YplusX, c->YminusX); + fe_mul(r->Y, r->Y, inv2); + + fe_copy(r->Z, c->Z); +} diff --git a/src/crypto/crypto-ops.h b/src/crypto/crypto-ops.h index 6fb6917c5..318af2a28 100644 --- a/src/crypto/crypto-ops.h +++ b/src/crypto/crypto-ops.h @@ -111,6 +111,7 @@ void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); void ge_p2_to_p3(ge_p3 *r, const ge_p2 *t); void ge_bytes_hash_to_ec(ge_p3 *, const void *, size_t); void ge_bytes_hash_to_ec_32(ge_p3 *, const unsigned char *); +void ge_cached_to_p2(ge_p2 *r, const ge_cached *c); void ge_p3_0(ge_p3 *h); void ge_sub(ge_p1p1 *, const ge_p3 *, const ge_cached *); @@ -138,8 +139,9 @@ void sc_invert(unsigned char*, const unsigned char*); void fe_sq(fe h, const fe f); int fe_isnonzero(const fe f); -int fe_cmp(const fe a, const fe b); +void fe_sub(fe h, const fe f, const fe g); void fe_mul(fe, const fe, const fe); void fe_frombytes(fe h, const unsigned char *s); void fe_invert(fe out, const fe z); void fe_tobytes(unsigned char *s, const fe h); +int fe_isnegative(const fe f); diff --git a/src/crypto/crypto-sugar.h b/src/crypto/crypto-sugar.h index 600fe9143..5542b9fb7 100644 --- a/src/crypto/crypto-sugar.h +++ b/src/crypto/crypto-sugar.h @@ -246,7 +246,7 @@ namespace crypto return result; } - // genrate 0 <= x < L + // generate 0 <= x < L void make_random() { unsigned char tmp[64]; @@ -497,7 +497,7 @@ namespace crypto zero(); } - // as we're using additive notation, zero means identity group element here and after + // as we're using additive notation, zero means identity group element (EC point (0, 1)) here and after void zero() { ge_p3_0(&m_p3); @@ -506,7 +506,11 @@ namespace crypto bool is_zero() const { // (0, 1) ~ (0, z, z, 0) - return fe_isnonzero(m_p3.X) * fe_cmp(m_p3.Y, m_p3.Z) == 0; + if (fe_isnonzero(m_p3.X) != 0) + return false; + fe y_minus_z; + fe_sub(y_minus_z, m_p3.Y, m_p3.Z); + return fe_isnonzero(y_minus_z) == 0; } bool is_in_main_subgroup() const @@ -669,6 +673,11 @@ namespace crypto return true; }; + friend bool operator!=(const point_t& lhs, const point_t& rhs) + { + return !(lhs == rhs); + }; + friend std::ostream& operator<<(std::ostream& ss, const point_t &v) { crypto::public_key pk = v.to_public_key(); diff --git a/src/currency_core/checkpoints_create.h b/src/currency_core/checkpoints_create.h index 059d190e8..e01526853 100644 --- a/src/currency_core/checkpoints_create.h +++ b/src/currency_core/checkpoints_create.h @@ -25,6 +25,7 @@ namespace currency ADD_CHECKPOINT(600000, "d9fe316086e1aaea07d94082973ec764eff5fc5a05ed6e1eca273cee59daeeb4"); ADD_CHECKPOINT(900000, "2205b73cd79d4937b087b02a8b001171b73c34464bc4a952834eaf7c2bd63e86"); ADD_CHECKPOINT(1161000, "96990d851b484e30190678756ba2a4d3a2f92b987e2470728ac1e38b2bf35908"); + ADD_CHECKPOINT(1480000, "5dd3381eec35e8b4eba4518bfd8eec682a4292761d92218fd59b9f0ffedad3fe"); #endif return true; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 4dfa5e12c..29e76ab18 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -212,6 +212,7 @@ #define GUI_SECURE_CONFIG_FILENAME "gui_secure_conf.bin" #define GUI_CONFIG_FILENAME "gui_settings.json" #define GUI_INTERNAL_CONFIG2 "gui_internal_config.json" +#define GUI_IPC_MESSAGE_CHANNEL_NAME CURRENCY_NAME_BASE "_message_que" diff --git a/src/currency_core/currency_format_utils_abstract.h b/src/currency_core/currency_format_utils_abstract.h index 451b46e3d..611511fc3 100644 --- a/src/currency_core/currency_format_utils_abstract.h +++ b/src/currency_core/currency_format_utils_abstract.h @@ -129,6 +129,7 @@ namespace currency } return found; } + //--------------------------------------------------------------- inline const txin_to_key& get_to_key_input_from_txin_v(const txin_v& in_v) { diff --git a/src/currency_core/offers_service_basics.h b/src/currency_core/offers_service_basics.h index 16d2990a4..809bf88bd 100644 --- a/src/currency_core/offers_service_basics.h +++ b/src/currency_core/offers_service_basics.h @@ -32,6 +32,7 @@ namespace bc_services std::string payment_types; // []money accept type(bank transaction, internet money, cash, etc) std::string deal_option; // []full amount, by parts std::string category; // [] + std::string preview_url; // [] uint8_t expiration_time; // n-days //----------------- @@ -50,6 +51,7 @@ namespace bc_services KV_SERIALIZE_N(deal_option, "do") KV_SERIALIZE_N(category, "cat") KV_SERIALIZE_N(expiration_time, "et") + KV_SERIALIZE_N(preview_url, "url") END_KV_SERIALIZE_MAP() }; diff --git a/src/currency_protocol/currency_protocol_handler.h b/src/currency_protocol/currency_protocol_handler.h index eaf06bda6..cae17241f 100644 --- a/src/currency_protocol/currency_protocol_handler.h +++ b/src/currency_protocol/currency_protocol_handler.h @@ -117,6 +117,7 @@ namespace currency int64_t m_last_median2local_time_difference; int64_t m_last_ntp2local_time_difference; uint32_t m_debug_ip_address; + bool m_disable_ntp; template bool post_notify(typename t_parametr::request& arg, currency_connection_context& context) diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index 39e42a3cb..03b93b672 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -23,6 +23,7 @@ namespace currency , m_last_median2local_time_difference(0) , m_last_ntp2local_time_difference(0) , m_debug_ip_address(0) + , m_disable_ntp(false) { if(!m_p2p) m_p2p = &m_p2p_stub; @@ -38,6 +39,8 @@ namespace currency bool t_currency_protocol_handler::init(const boost::program_options::variables_map& vm) { m_relay_que_thread = std::thread([this](){relay_que_worker();}); + if (command_line::has_arg(vm, command_line::arg_disable_ntp)) + m_disable_ntp = command_line::get_arg(vm, command_line::arg_disable_ntp); return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -834,6 +837,12 @@ namespace currency LOG_PRINT_MAGENTA("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << ")", ((m_last_median2local_time_difference >= 3) ? LOG_LEVEL_2 : LOG_LEVEL_3)); if (std::abs(m_last_median2local_time_difference) > TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE) { + // treat as error getting ntp time + if (m_disable_ntp) + { + LOG_PRINT_RED("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << ") while NTP is disabled", LOG_LEVEL_0); + return false; + } int64_t ntp_time = tools::get_ntp_time(); LOG_PRINT_L2("NTP: received time " << ntp_time << " (" << epee::misc_utils::get_time_str_v2(ntp_time) << "), diff: " << std::showpos << get_core_time() - ntp_time); if (ntp_time == 0) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 8cbaf4f1e..889c1c55e 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -164,6 +164,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, command_line::arg_force_predownload); command_line::add_arg(desc_cmd_sett, command_line::arg_validate_predownload); command_line::add_arg(desc_cmd_sett, command_line::arg_predownload_link); + command_line::add_arg(desc_cmd_sett, command_line::arg_disable_ntp); arg_market_disable.default_value = true; diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 083c2afd1..646e4d3bd 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -121,6 +121,10 @@ MainWindow::~MainWindow() delete m_channel; m_channel = nullptr; } + if (m_ipc_worker.joinable()) + { + m_ipc_worker.join(); + } } void MainWindow::on_load_finished(bool ok) @@ -740,8 +744,115 @@ void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, c } } +bool MainWindow::remove_ipc() +{ + try { + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + } + catch (...) + { + } + return true; +} + + +bool MainWindow::init_ipc_server() +{ + + //in case previous instance wasn't close graceful, ipc channel will remain open and new creation will fail, so we + //trying to close it anyway before open, to make sure there are no dead channels. If there are another running instance, it wom't + //let channel to close, so it will fail later on creating channel + remove_ipc(); +#define GUI_IPC_BUFFER_SIZE 10000 + try { + //Create a message queue. + std::shared_ptr pmq(new boost::interprocess::message_queue(boost::interprocess::create_only //only create + , GUI_IPC_MESSAGE_CHANNEL_NAME //name + , 100 //max message number + , GUI_IPC_BUFFER_SIZE //max message size + )); + + m_ipc_worker = std::thread([this, pmq]() + { + //m_ipc_worker; + try + { + unsigned int priority = 0; + boost::interprocess::message_queue::size_type recvd_size = 0; + + while (m_gui_deinitialize_done_1 == false) + { + std::string buff(GUI_IPC_BUFFER_SIZE, ' '); + bool data_received = pmq->timed_receive((void*)buff.data(), GUI_IPC_BUFFER_SIZE, recvd_size, priority, boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) + boost::posix_time::milliseconds(1000)); + if (data_received && recvd_size != 0) + { + buff.resize(recvd_size, '*'); + handle_ipc_event(buff);//todo process token + } + } + remove_ipc(); + LOG_PRINT_L0("IPC Handling thread finished"); + } + catch (const std::exception& ex) + { + remove_ipc(); + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + LOG_ERROR("Failed to receive IPC que: " << ex.what()); + } + + catch (...) + { + remove_ipc(); + LOG_ERROR("Failed to receive IPC que: unknown exception"); + } + }); + } + catch(const std::exception& ex) + { + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + LOG_ERROR("Failed to initialize IPC que: " << ex.what()); + return false; + } + + catch (...) + { + boost::interprocess::message_queue::remove(GUI_IPC_MESSAGE_CHANNEL_NAME); + LOG_ERROR("Failed to initialize IPC que: unknown exception"); + return false; + } + return true; +} + + +bool MainWindow::handle_ipc_event(const std::string& arguments) +{ + std::string zzz = std::string("Received IPC: ") + arguments.c_str(); + std::cout << zzz;//message_box(zzz.c_str()); + + handle_deeplink_click(arguments.c_str()); + + return true; +} + +bool MainWindow::handle_deeplink_params_in_commandline() +{ + std::string deep_link_params = command_line::get_arg(m_backend.get_arguments(), command_line::arg_deeplink); + + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, GUI_IPC_MESSAGE_CHANNEL_NAME); + mq.send(deep_link_params.data(), deep_link_params.size(), 0); + return false; + } + catch (...) + { + //ui not launched yet + return true; + } +} + bool MainWindow::init_backend(int argc, char* argv[]) { + TRY_ENTRY(); std::string command_line_fail_details; if (!m_backend.init_command_line(argc, argv, command_line_fail_details)) @@ -750,6 +861,12 @@ bool MainWindow::init_backend(int argc, char* argv[]) return false; } + if (command_line::has_arg(m_backend.get_arguments(), command_line::arg_deeplink)) + { + if (!handle_deeplink_params_in_commandline()) + return false; + } + if (!init_window()) { this->show_msg_box("Failed to main screen launch, check logs for the more detais."); @@ -770,6 +887,12 @@ bool MainWindow::init_backend(int argc, char* argv[]) QLoggingCategory::setFilterRules("*=true"); // enable all logs } + if (!init_ipc_server()) + { + this->show_msg_box("Failed to initialize IPC server, check debug logs for more details."); + return false; + } + return true; CATCH_ENTRY2(false); } diff --git a/src/gui/qt-daemon/application/mainwindow.h b/src/gui/qt-daemon/application/mainwindow.h index 57fcf1293..4f7af71d6 100644 --- a/src/gui/qt-daemon/application/mainwindow.h +++ b/src/gui/qt-daemon/application/mainwindow.h @@ -4,12 +4,15 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#pragma once #include #include +#include #include "wallet/view_iface.h" #include "serialization/keyvalue_helper_structs.h" + #ifndef Q_MOC_RUN #include "wallet/wallets_manager.h" #include "currency_core/offers_services_helpers.h" @@ -58,6 +61,7 @@ class MainWindow : public QMainWindow, bool init_backend(int argc, char* argv[]); bool show_inital(); void show_notification(const std::string& title, const std::string& message); + bool handle_ipc_event(const std::string& arguments); struct app_config { @@ -192,6 +196,7 @@ class MainWindow : public QMainWindow, void on_core_event(const QString method_name); //general function void set_options(const QString str); //general function void get_wallet_name(); + void handle_deeplink_click(const QString str); private: //-------------------- i_core_event_handler -------------------- @@ -220,7 +225,7 @@ class MainWindow : public QMainWindow, void contextMenuEvent(QContextMenuEvent * event); void changeEvent(QEvent *e); void on_maximized(); - + bool handle_deeplink_params_in_commandline(); //void setOrientation(Qt::ScreenOrientation orientation); @@ -234,6 +239,9 @@ class MainWindow : public QMainWindow, bool store_app_config(); bool load_app_config(); bool init_window(); + bool init_ipc_server(); + bool remove_ipc(); + std::string get_wallet_log_prefix(size_t wallet_id) const { return m_backend.get_wallet_log_prefix(wallet_id); } @@ -256,6 +264,7 @@ class MainWindow : public QMainWindow, app_config m_config; epee::locked_object> m_wallet_states; + std::thread m_ipc_worker; struct events_que_struct { std::list m_que; diff --git a/src/gui/qt-daemon/application/urleventfilter.cpp b/src/gui/qt-daemon/application/urleventfilter.cpp index d7e4e35ef..910b10f45 100644 --- a/src/gui/qt-daemon/application/urleventfilter.cpp +++ b/src/gui/qt-daemon/application/urleventfilter.cpp @@ -7,10 +7,13 @@ bool URLEventFilter::eventFilter(QObject *obj, QEvent *event) QFileOpenEvent *fileEvent = static_cast(event); if(!fileEvent->url().isEmpty()) { - QMessageBox msg; - msg.setText(fileEvent->url().toString()); - msg.exec(); + m_pmainwindow->handle_deeplink_click(fileEvent->url().toString()); + //QMessageBox msg; + //msg.setText(fileEvent->url().toString()); + //msg.exec(); + return true; } + return true; } else { // standard event processing return QObject::eventFilter(obj, event); diff --git a/src/gui/qt-daemon/application/urleventfilter.h b/src/gui/qt-daemon/application/urleventfilter.h index 54341dbdf..1e3e0dc21 100644 --- a/src/gui/qt-daemon/application/urleventfilter.h +++ b/src/gui/qt-daemon/application/urleventfilter.h @@ -1,12 +1,17 @@ #include #include #include +#include "mainwindow.h" class URLEventFilter : public QObject { Q_OBJECT public: - URLEventFilter() : QObject(){}; + URLEventFilter(MainWindow* pmainwindow) : m_pmainwindow(pmainwindow),QObject() + {}; protected: bool eventFilter(QObject *obj, QEvent *event) override; + +private: + MainWindow* m_pmainwindow; }; \ No newline at end of file diff --git a/src/gui/qt-daemon/layout b/src/gui/qt-daemon/layout index 93802cb8f..709a1e6a3 160000 --- a/src/gui/qt-daemon/layout +++ b/src/gui/qt-daemon/layout @@ -1 +1 @@ -Subproject commit 93802cb8fe1c79daf320aa4b72ba454d27da31d7 +Subproject commit 709a1e6a3eb5ae7af48bbadf6b4c512b637b75b3 diff --git a/src/gui/qt-daemon/main.cpp b/src/gui/qt-daemon/main.cpp index f32dde0fa..39ecae9df 100644 --- a/src/gui/qt-daemon/main.cpp +++ b/src/gui/qt-daemon/main.cpp @@ -66,11 +66,6 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); - -#ifdef Q_OS_DARWIN - URLEventFilter url_event_filter; - app.installEventFilter(&url_event_filter); -#endif MainWindow viewer; if (!viewer.init_backend(argc, argv)) @@ -78,6 +73,11 @@ int main(int argc, char *argv[]) return 1; } +#ifdef Q_OS_DARWIN + URLEventFilter url_event_filter(&viewer); + app.installEventFilter(&url_event_filter); +#endif + app.installNativeEventFilter(&viewer); viewer.setWindowTitle(CURRENCY_NAME_BASE); viewer.show_inital(); diff --git a/src/version.h.in b/src/version.h.in index 049250583..a9c7f0d98 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -5,9 +5,9 @@ #define PROJECT_MAJOR_VERSION "1" #define PROJECT_MINOR_VERSION "4" -#define PROJECT_REVISION "0" +#define PROJECT_REVISION "1" #define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION -#define PROJECT_VERSION_BUILD_NO 138 +#define PROJECT_VERSION_BUILD_NO 142 #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 "]" diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5c9028f27..cbceb80b3 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3258,7 +3258,7 @@ void wallet2::get_recent_transfers_history(std::vector& return true; } +const po::variables_map& wallets_manager::get_arguments() +{ + return m_vm; +} + std::string wallets_manager::get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist, bool exclude_mining_txs) { GET_WALLET_BY_ID(wallet_id, w); diff --git a/src/wallet/wallets_manager.h b/src/wallet/wallets_manager.h index 10d6a1036..ac64041c3 100644 --- a/src/wallet/wallets_manager.h +++ b/src/wallet/wallets_manager.h @@ -97,6 +97,8 @@ class wallets_manager : public i_backend_wallet_callback bool quick_clear_wallets_no_save(); bool send_stop_signal(); bool get_opened_wallets(std::list& result); + const po::variables_map& get_arguments(); + 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& seed_phrase, const std::string& seed_password, view::open_wallet_response& owr); diff --git a/tests/functional_tests/crypto_tests.cpp b/tests/functional_tests/crypto_tests.cpp index 86d004012..83c94b8b3 100644 --- a/tests/functional_tests/crypto_tests.cpp +++ b/tests/functional_tests/crypto_tests.cpp @@ -959,33 +959,85 @@ TEST(crypto, hp) TEST(crypto, cn_fast_hash_perf) { - return true; - crypto::hash h = { 3, 14, 15, 9, 26 }; + //return true; + const crypto::hash h_initial = *(crypto::hash*)(&scalar_t::random()); + + std::vector> test_data; + test_data.push_back(std::vector(32, 0)); + test_data.push_back(std::vector(63, 0)); + test_data.push_back(std::vector(127, 0)); + test_data.push_back(std::vector(135, 0)); + test_data.push_back(std::vector(255, 0)); + test_data.push_back(std::vector(271, 0)); // 271 = 136 * 2 - 1 + test_data.push_back(std::vector(2030, 0)); + + for (size_t j = 0, sz = test_data.size(); j < sz; ++j) + crypto::generate_random_bytes(test_data[j].size(), test_data[j].data()); + + struct times_t + { + uint64_t t_old{ 0 }, t_new{ 0 }; + crypto::hash h_old{}; + double diff{ 0 }; + }; + std::vector results(test_data.size()); - size_t n = 100000; + size_t n = 50000; double diff_sum = 0; - for (size_t j = 0; j < 20; ++j) + for (size_t k = 0; k < 50; ++k) { - TIME_MEASURE_START(t_old); - for (size_t i = 0; i < n; ++i) - cn_fast_hash_old(&h, sizeof h, (char*)&h); - TIME_MEASURE_FINISH(t_old); + for (size_t j = 0, sz = test_data.size(); j < sz; ++j) + { + crypto::hash h = h_initial; + TIME_MEASURE_START(t_old); + for (size_t i = 0; i < n; ++i) + { + *(crypto::hash*)(test_data[j].data()) = h; + cn_fast_hash_old(test_data[j].data(), test_data[j].size(), (char*)&h); + } + TIME_MEASURE_FINISH(t_old); + results[j].t_old = t_old; + results[j].h_old = h; + } + + for (size_t j = 0, sz = test_data.size(); j < sz; ++j) + { + crypto::hash h = h_initial; + TIME_MEASURE_START(t_new); + for (size_t i = 0; i < n; ++i) + { + *(crypto::hash*)(test_data[j].data()) = h; + cn_fast_hash(test_data[j].data(), test_data[j].size(), (char*)&h); + } + TIME_MEASURE_FINISH(t_new); + results[j].t_new = t_new; + ASSERT_EQ(h, results[j].h_old); + } + + std::stringstream ss; + double diff_round = 0; + for (size_t j = 0, sz = test_data.size(); j < sz; ++j) + { + double diff = ((int64_t)results[j].t_old - (int64_t)results[j].t_new) / (double)n; - TIME_MEASURE_START(t); - for (size_t i = 0; i < n; ++i) - cn_fast_hash(&h, sizeof h, (char*)&h); - TIME_MEASURE_FINISH(t); + ss << std::fixed << std::setprecision(3) << results[j].t_old / (double)n << "/" << + std::fixed << std::setprecision(3) << results[j].t_new / (double)n << " "; - double diff = ((int64_t)t_old - (int64_t)t) / (double)n; + results[j].diff += diff; + diff_round += diff; + } - LOG_PRINT_L0("cn_fast_hash (old/new): " << std::fixed << std::setprecision(3) << t_old / (double)n << " " << - std::fixed << std::setprecision(3) << t * 1.0 / n << " mcs diff => " << std::fixed << std::setprecision(4) << diff); + diff_sum += diff_round; - diff_sum += diff; + LOG_PRINT_L0("cn_fast_hash (old/new) [" << std::setw(2) << k << "]: " << ss.str() << " mcs, diff_round = " << std::fixed << std::setprecision(4) << diff_round << + " diff_sum = " << std::fixed << std::setprecision(4) << diff_sum); } - std::cout << h << " diff sum: " << diff_sum << std::endl; + std::stringstream ss; + for (size_t j = 0, sz = results.size(); j < sz; ++j) + ss << std::fixed << std::setprecision(4) << results[j].diff << " "; + LOG_PRINT_L0(" " << ss.str()); return true; } @@ -1622,6 +1674,135 @@ TEST(crypto, calc_lsb_32) return true; } +TEST(crypto, torsion_elements) +{ + // let ty = -sqrt((-sqrt(D+1)-1) / D), is_neg(ty) == false + // canonical serialization sig order EC point + // 26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05 0 8 (sqrt(-1)*ty, ty) + // 0000000000000000000000000000000000000000000000000000000000000000 0 4 (sqrt(-1), 0) + // c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a 0 8 (sqrt(-1)*ty, -ty) + // ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f 0 2 (0, -1) + // c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa 1 8 (-sqrt(-1)*ty, -ty) + // 0000000000000000000000000000000000000000000000000000000000000080 1 4 (-sqrt(-1), 0) + // 26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85 1 8 (-sqrt(-1)*ty, ty) + + struct canonical_torsion_elements_t + { + const char* string; + bool sign; + uint8_t order; + uint8_t incorrect_order_0; + uint8_t incorrect_order_1; + }; + + canonical_torsion_elements_t canonical_torsion_elements[] = { + {"26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05", false, 8, 4, 7}, + {"0000000000000000000000000000000000000000000000000000000000000000", false, 4, 2, 3}, + {"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a", false, 8, 4, 7}, + {"ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", false, 2, 1, 3}, + {"c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", true, 8, 4, 7}, + {"0000000000000000000000000000000000000000000000000000000000000080", true, 4, 2, 3}, + {"26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85", true, 8, 4, 7} + }; + + point_t tor; + + for (size_t i = 0, n = sizeof canonical_torsion_elements / sizeof canonical_torsion_elements[0]; i < n; ++i) + { + const canonical_torsion_elements_t& el = canonical_torsion_elements[i]; + ASSERT_TRUE(tor.from_string(el.string)); + ASSERT_FALSE(tor.is_zero()); + ASSERT_FALSE(tor.is_in_main_subgroup()); + + ASSERT_EQ((fe_isnegative(tor.m_p3.X) != 0), el.sign); + + ASSERT_FALSE(el.incorrect_order_0 * tor == c_point_0); + ASSERT_FALSE(el.incorrect_order_1 * tor == c_point_0); + ASSERT_TRUE(el.order * tor == c_point_0); + } + + // non-canonical elements should not load at all (thanks to the checks in ge_frombytes_vartime) + + const char* noncanonical_torsion_elements[] = { + "0100000000000000000000000000000000000000000000000000000000000080", // (-0, 1) + "ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", // (-0, -1) + "EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F", // (0, 2*255-18) + "EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", // (-0, 2*255-18) + "EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F", // (sqrt(-1), 2*255-19) + "EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" // (-sqrt(-1), 2*255-19) + }; + + for (size_t i = 0, n = sizeof noncanonical_torsion_elements / sizeof noncanonical_torsion_elements[0]; i < n; ++i) + { + ASSERT_FALSE(tor.from_string(noncanonical_torsion_elements[i])); + } + + return true; +} + +TEST(crypto, point_is_zero) +{ + static const fe fancy_p = { -19, 33554432, -1, 33554432, -1, 33554432, -1, 33554432, -1, 33554432 }; // 2**255 - 19 + static const fe fancy_p_plus_1 = { -18, 33554432, -1, 33554432, -1, 33554432, -1, 33554432, -1, 33554432 }; // 2**255 - 18 + static const fe f_one = { 1 }; + + ASSERT_TRUE(fe_isnonzero(fancy_p) == 0); + ASSERT_TRUE(fe_isnonzero(fancy_p_plus_1) != 0); + + fe f_r, f_x; + fe_frombytes(f_x, scalar_t::random().data()); + fe_mul(f_r, f_x, fancy_p); + ASSERT_TRUE(fe_isnonzero(f_r) == 0); + + fe_sub(f_r, fancy_p_plus_1, f_one); + ASSERT_TRUE(fe_isnonzero(f_r) == 0); + + // is_zero + + point_t p; + memset(&p.m_p3, 0, sizeof p.m_p3); + memcpy(&p.m_p3.X, fancy_p, sizeof p.m_p3.X); // X = 2**255-19 + memcpy(&p.m_p3.Y, fancy_p_plus_1, sizeof p.m_p3.Y); // Y = 2**255-19+1 + p.m_p3.Z[0] = 1; + // {P, P+1, 1, 0} == {0, 1} (the identity point) + + ASSERT_TRUE(p.is_zero()); + + + memset(&p.m_p3, 0, sizeof p.m_p3); + memcpy(&p.m_p3.X, fancy_p, sizeof p.m_p3.X); // X = 2**255-19 + memcpy(&p.m_p3.Y, fancy_p_plus_1, sizeof p.m_p3.Y); // Y = 2**255-19+1 + p.m_p3.Z[0] = -1; + // {P, P+1, -1, 0} == {0, -1} (not an identity point, torsion element order 2) + + ASSERT_FALSE(p.is_zero()); + + memset(&p.m_p3, 0, sizeof p.m_p3); + p.m_p3.Y[0] = 2; + p.m_p3.Z[0] = 2; + // {0, 2, 2, 0} == {0, 1} (the identity point) + + ASSERT_TRUE(p.is_zero()); + + // all fe 10 components must be in [-33554432, 33554432] (curve25519-20060209.pdf page 9) + // 2**0 2**26 2**51 2**77 2**102 2**128 2**153 2**179 2**204 2*230 + fe a0 = { 7172245, 16777211, 922265, 8160646, 9625798, -12989394, 10843498, 6987154, 15156548, -5214544 }; + fe a1 = { 7172245, -16777221, 922266, 8160646, 9625798, -12989394, 10843498, 6987154, 15156548, -5214544 }; + // note, a0 == a1: + // 16777211 * 2**26 + 922265 * 2**51 = 2076757281067996545024 + // -16777221 * 2**26 + 922266 * 2**51 = 2076757281067996545024 + + memset(&p.m_p3, 0, sizeof p.m_p3); + memcpy(&p.m_p3.Y, &a0, sizeof a0); + memcpy(&p.m_p3.Z, &a1, sizeof a1); + // {0, x, x, 0} == {0, 1, 1, 0} == {0, 1} (the identity point) + + ASSERT_TRUE(p.is_zero()); + + return true; +} + + // // test's runner // diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index c3f0a77a9..e8d7a2ed7 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -23,6 +23,8 @@ #include "print_struct_to_json.h" #include "free_space_check.h" #include "htlc_hash_tests.h" +#include "threads_pool_tests.h" + int main(int argc, char** argv) { @@ -33,21 +35,23 @@ int main(int argc, char** argv) epee::log_space::log_singletone::get_default_log_file().c_str(), epee::log_space::log_singletone::get_default_log_folder().c_str()); - - std::string buf1 = tools::get_varint_data(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX); - std::string buf2 = tools::get_varint_data(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX); - std::string buf3 = tools::get_varint_data(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX); - std::string buf4 = tools::get_varint_data(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX); - std::string buf5 = tools::get_varint_data(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX); - - std::cout << "Buf1: " << epee::string_tools::buff_to_hex_nodelimer(buf1) << ENDL; - std::cout << "Buf2: " << epee::string_tools::buff_to_hex_nodelimer(buf2) << ENDL; - std::cout << "Buf3: " << epee::string_tools::buff_to_hex_nodelimer(buf3) << ENDL; - std::cout << "Buf4: " << epee::string_tools::buff_to_hex_nodelimer(buf4) << ENDL; - std::cout << "Buf5: " << epee::string_tools::buff_to_hex_nodelimer(buf5) << ENDL; - - do_htlc_hash_tests(); + thread_pool_tests(); + +// std::string buf1 = tools::get_varint_data(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX); +// std::string buf2 = tools::get_varint_data(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX); +// std::string buf3 = tools::get_varint_data(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX); +// std::string buf4 = tools::get_varint_data(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX); +// std::string buf5 = tools::get_varint_data(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX); +// +// std::cout << "Buf1: " << epee::string_tools::buff_to_hex_nodelimer(buf1) << ENDL; +// std::cout << "Buf2: " << epee::string_tools::buff_to_hex_nodelimer(buf2) << ENDL; +// std::cout << "Buf3: " << epee::string_tools::buff_to_hex_nodelimer(buf3) << ENDL; +// std::cout << "Buf4: " << epee::string_tools::buff_to_hex_nodelimer(buf4) << ENDL; +// std::cout << "Buf5: " << epee::string_tools::buff_to_hex_nodelimer(buf5) << ENDL; +// +// + //do_htlc_hash_tests(); //run_serialization_performance_test(); //return 1; //run_core_market_performance_tests(100000); diff --git a/tests/performance_tests/threads_pool_tests.h b/tests/performance_tests/threads_pool_tests.h new file mode 100644 index 000000000..6999ac303 --- /dev/null +++ b/tests/performance_tests/threads_pool_tests.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 The Zano 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 +#include "include_base_utils.h" +#include "common/threads_pool.h" + + +inline +void thread_pool_tests_simple() +{ + { + utils::threads_pool pool; + pool.init(); + std::atomic count_jobs_finished = 0; + size_t i = 0; + for (; i != 10; i++) + { + pool.add_job([&, i]() {LOG_PRINT_L0("Job " << i << " started"); epee::misc_utils::sleep_no_w(10000); ++count_jobs_finished; LOG_PRINT_L0("Job " << i << " finished"); }); + } + while (count_jobs_finished != i) + { + epee::misc_utils::sleep_no_w(500); + } + LOG_PRINT_L0("All jobs finished"); + } + LOG_PRINT_L0("Scope left"); +} + +inline +void thread_pool_tests() +{ + { + utils::threads_pool pool; + pool.init(); + std::atomic count_jobs_finished = 0; + + utils::threads_pool::jobs_container jobs; + size_t i = 0; + for (; i != 10; i++) + { + utils::threads_pool::add_job_to_container(jobs, [&, i]() {LOG_PRINT_L0("Job " << i << " started"); epee::misc_utils::sleep_no_w(10000); ++count_jobs_finished; LOG_PRINT_L0("Job " << i << " finished"); }); + } + + pool.add_batch_and_wait(jobs); + if (count_jobs_finished != i) + { + LOG_ERROR("Test failed"); + return; + } + LOG_PRINT_L0("All jobs finished"); + } + LOG_PRINT_L0("Scope left"); +} \ No newline at end of file diff --git a/utils/Zano.sh b/utils/Zano.sh index e0eac8cc0..6e4d22d87 100755 --- a/utils/Zano.sh +++ b/utils/Zano.sh @@ -29,7 +29,7 @@ create_desktop_icon() echo GenericName=Zano | tee -a $target_file_name > /dev/null echo Comment=Privacy blockchain | tee -a $target_file_name > /dev/null echo Icon=$script_dir/html/files/desktop_linux_icon.png | tee -a $target_file_name > /dev/null - echo Exec=$script_dir/Zano.sh %u | tee -a $target_file_name > /dev/null + echo Exec=$script_dir/Zano.sh --deeplink-params=%u | tee -a $target_file_name > /dev/null echo Terminal=true | tee -a $target_file_name > /dev/null echo Type=Application | tee -a $target_file_name > /dev/null echo "Categories=Qt;Utility;" | tee -a $target_file_name > /dev/null diff --git a/utils/deeplink.rm b/utils/deeplink.rm new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/utils/deeplink.rm @@ -0,0 +1 @@ + diff --git a/utils/setup_64.iss b/utils/setup_64.iss index adee27a88..364a9767b 100644 --- a/utils/setup_64.iss +++ b/utils/setup_64.iss @@ -53,7 +53,7 @@ Root: HKCR; Subkey: "ZanoWalletDataFile\DefaultIcon"; ValueType: string; ValueNa Root: HKCR; Subkey: "ZanoWalletDataKyesFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe,0" Root: HKCR; Subkey: "Zano"; ValueType: string; ValueName: "URL Protocol"; ValueData: "" -Root: HKCR; Subkey: "Zano\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe %1" +Root: HKCR; Subkey: "Zano\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe --deeplink-params=%1" [Files]