1
0
Fork 0
forked from lthn/blockchain

Merge branch 'release'

This commit is contained in:
cryptozoidberg 2022-03-15 19:14:37 +02:00
commit c5656534c4
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
33 changed files with 687 additions and 64 deletions

View file

@ -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})

View file

@ -28,6 +28,7 @@ namespace command_line
const arg_descriptor<bool> arg_show_rpc_autodoc = { "show_rpc_autodoc", "Display rpc auto-generated documentation template" };
const arg_descriptor<bool> arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true };
const arg_descriptor<bool> 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<bool> 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<bool> 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<bool> arg_validate_predownload = { "validate-predownload", "Paranoid mode, re-validate each block from pre-downloaded database and rebuild own database", };
const arg_descriptor<std::string> arg_predownload_link = { "predownload-link", "Override url for blockchain database pre-downloading", "", true };
const arg_descriptor<std::string> arg_deeplink = { "deeplink-params", "Deeplink parameter, in that case app just forward params to running app", "", true };
}

View file

@ -216,6 +216,7 @@ namespace command_line
extern const arg_descriptor<bool> arg_show_details;
extern const arg_descriptor<bool> arg_show_rpc_autodoc;
extern const arg_descriptor<bool> arg_disable_upnp;
extern const arg_descriptor<bool> arg_disable_ntp;
extern const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync;
extern const arg_descriptor<bool> arg_disable_stop_on_low_free_space;
extern const arg_descriptor<bool> arg_enable_offers_service;
@ -224,4 +225,5 @@ namespace command_line
extern const arg_descriptor<bool> arg_force_predownload;
extern const arg_descriptor<bool> arg_validate_predownload;
extern const arg_descriptor<std::string> arg_predownload_link;
extern const arg_descriptor<std::string> arg_deeplink;
}

View file

@ -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<class t_cb>
void enumerate_items(t_cb cb)const
{

View file

@ -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 };

153
src/common/threads_pool.h Normal file
View file

@ -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 <thread>
#include <string>
#include <boost/thread.hpp>
namespace utils
{
struct call_executor_base
{
virtual void execute() = 0;
};
template<typename t_executor_func>
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<typename t_executor_func>
std::shared_ptr<call_executor_base> build_call_executor(t_executor_func func)
{
std::shared_ptr<call_executor_base> res(static_cast<call_executor_base*>(new call_executor_t<t_executor_func>(func)));
return res;
}
class threads_pool
{
public:
typedef std::list<std::shared_ptr<call_executor_base>> jobs_container;
template<typename t_executor_func>
static void add_job_to_container(jobs_container& cntr, t_executor_func func)
{
cntr.push_back(std::shared_ptr<call_executor_base>(static_cast<call_executor_base*>(new call_executor_t<t_executor_func>(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<typename t_executor_func>
bool add_job(t_executor_func func)
{
{
std::unique_lock<std::mutex> 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<size_t> cnt = 0;
for (const auto& jb : cntr)
{
call_executor_base* pjob = jb.get();
add_job([&, pjob]() {
pjob->execute();
{
std::lock_guard<std::mutex> lock(batch_mutex);
cnt++;
}
batch_condition.notify_one();
});
}
std::unique_lock<std::mutex> 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<call_executor_base> job;
{
std::unique_lock<std::mutex> 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<std::thread> m_threads;
std::atomic<bool> m_is_stop;
std::atomic<int64_t> m_threads_counter;
};
}

View file

@ -12,6 +12,7 @@
using namespace epee;
#include <boost/program_options.hpp>
//#include <boost/interprocess/ipc/message_queue.hpp>
#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<std::string> arg_pack_file = {"pack-file", "perform gzip-packing and calculate hash for a given file", "", true };
const command_line::arg_descriptor<std::string> arg_unpack_file = {"unpack-file", "Perform gzip-unpacking and calculate hash for a given file", "", true };
const command_line::arg_descriptor<std::string> arg_target_file = {"target-file", "Specify target file for pack-file and unpack-file commands", "", true };
//const command_line::arg_descriptor<std::string> arg_send_ipc = {"send-ipc", "Send IPC request to UI", "", true };
}
typedef COMMAND_REQUEST_STAT_INFO_T<t_currency_protocol_handler<core>::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;

View file

@ -325,7 +325,7 @@ Preconditions:
|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 @@ Postconditions:
|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);
}

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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"

View file

@ -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)
{

View file

@ -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()
};

View file

@ -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<class t_parametr>
bool post_notify(typename t_parametr::request& arg, currency_connection_context& context)

View file

@ -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<t_core>::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)

View file

@ -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;

View file

@ -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<boost::interprocess::message_queue> 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);
}

View file

@ -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 <QtWidgets>
#include <QWebChannel>
#include <boost/interprocess/ipc/message_queue.hpp>
#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 @@ public:
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 @@ signals:
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 @@ private:
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 @@ private:
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 @@ private:
app_config m_config;
epee::locked_object<std::map<uint64_t, uint64_t>> m_wallet_states;
std::thread m_ipc_worker;
struct events_que_struct
{
std::list<currency::core_event> m_que;

View file

@ -7,10 +7,13 @@ bool URLEventFilter::eventFilter(QObject *obj, QEvent *event)
QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(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);

View file

@ -1,12 +1,17 @@
#include <QObject>
#include <QFileOpenEvent>
#include <QDebug>
#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;
};

@ -1 +1 @@
Subproject commit 93802cb8fe1c79daf320aa4b72ba454d27da31d7
Subproject commit 709a1e6a3eb5ae7af48bbadf6b4c512b637b75b3

View file

@ -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();

View file

@ -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 "]"

View file

@ -3258,7 +3258,7 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
void wallet2::wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index) {
ss << index << ",";
ss << epee::misc_utils::get_time_str_v2(wti.timestamp) << ",";
ss << epee::misc_utils::get_time_str(wti.timestamp) << ",";
ss << print_money(wti.amount) << ",";
ss << "\"" << wti.comment << "\",";
ss << "[";

View file

@ -183,6 +183,8 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai
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_deeplink);
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_ntp);
#ifndef MOBILE_WALLET_BUILD
@ -247,6 +249,7 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai
m_qt_logs_enbaled = command_line::get_arg(m_vm, arg_enable_qt_logs);
m_qt_dev_tools = command_line::get_arg(m_vm, arg_qt_dev_tools);
return true;
CATCH_ENTRY2(false);
}
@ -988,6 +991,11 @@ bool wallets_manager::get_opened_wallets(std::list<view::open_wallet_response>&
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);

View file

@ -97,6 +97,8 @@ public:
bool quick_clear_wallets_no_save();
bool send_stop_signal();
bool get_opened_wallets(std::list<view::open_wallet_response>& 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);

View file

@ -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());
size_t n = 100000;
std::vector<std::vector<uint8_t>> test_data;
test_data.push_back(std::vector<uint8_t>(32, 0));
test_data.push_back(std::vector<uint8_t>(63, 0));
test_data.push_back(std::vector<uint8_t>(127, 0));
test_data.push_back(std::vector<uint8_t>(135, 0));
test_data.push_back(std::vector<uint8_t>(255, 0));
test_data.push_back(std::vector<uint8_t>(271, 0)); // 271 = 136 * 2 - 1
test_data.push_back(std::vector<uint8_t>(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<times_t> results(test_data.size());
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;
}
TIME_MEASURE_START(t);
for (size_t i = 0; i < n; ++i)
cn_fast_hash(&h, sizeof h, (char*)&h);
TIME_MEASURE_FINISH(t);
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);
}
double diff = ((int64_t)t_old - (int64_t)t) / (double)n;
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;
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);
ss << std::fixed << std::setprecision(3) << results[j].t_old / (double)n << "/" <<
std::fixed << std::setprecision(3) << results[j].t_new / (double)n << " ";
diff_sum += diff;
results[j].diff += diff;
diff_round += diff;
}
diff_sum += diff_round;
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
//

View file

@ -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<uint64_t>(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX);
std::string buf2 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
std::string buf3 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX);
std::string buf4 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX);
std::string buf5 = tools::get_varint_data<uint64_t>(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;
thread_pool_tests();
do_htlc_hash_tests();
// std::string buf1 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX);
// std::string buf2 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
// std::string buf3 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX);
// std::string buf4 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX);
// std::string buf5 = tools::get_varint_data<uint64_t>(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);

View file

@ -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 <string>
#include "include_base_utils.h"
#include "common/threads_pool.h"
inline
void thread_pool_tests_simple()
{
{
utils::threads_pool pool;
pool.init();
std::atomic<uint64_t> 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<uint64_t> 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");
}

View file

@ -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

1
utils/deeplink.rm Normal file
View file

@ -0,0 +1 @@

View file

@ -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]