1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into release

This commit is contained in:
cryptozoidberg 2021-11-25 14:38:27 +01:00
commit 911744703f
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
42 changed files with 620 additions and 172 deletions

View file

@ -376,7 +376,7 @@ namespace epee
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
{
async_console_handler console_handler;
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, _1, _2, handlr), prompt, usage);
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, boost::placeholders::_1, boost::placeholders::_2, handlr), prompt, usage);
}
template<class t_server, class t_handler>
@ -460,7 +460,7 @@ namespace epee
/*template<class t_srv>
bool start_handling(t_srv& srv, const std::string& usage_string = "")
{
start_default_console_handler_no_srv_param(&srv, boost::bind(&console_handlers_binder::process_command_str, this, _1));
start_default_console_handler_no_srv_param(&srv, boost::bind(&console_handlers_binder::process_command_str, this, boost::placeholders::_1));
return true;
}*/
@ -489,7 +489,7 @@ namespace epee
/*template<class t_srv>
bool run_handling(t_srv& srv, const std::string& usage_string)
{
return run_default_console_handler_no_srv_param(&srv, boost::bind<bool>(&console_handlers_binder::process_command_str, this, _1), usage_string);
return run_default_console_handler_no_srv_param(&srv, boost::bind<bool>(&console_handlers_binder::process_command_str, this, boost::placeholders::_1), usage_string);
}*/
};
@ -510,7 +510,7 @@ namespace epee
bool run_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string)
{
return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, _1, _2), prompt, usage_string);
return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, boost::placeholders::_1, boost::placeholders::_2), prompt, usage_string);
}
void stop_handling()

View file

@ -0,0 +1,40 @@
// Copyright (c) 2006-2021, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
namespace epee
{
template<class _Ty1, class _Ty2>
struct kvserializable_pair : public std::pair<_Ty1, _Ty2>
{
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(first)
KV_SERIALIZE(second)
END_KV_SERIALIZE_MAP()
};
}

View file

@ -87,7 +87,7 @@ DISABLE_VS_WARNINGS(4996)
POP_VS_WARNINGS
if(pt)
strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt );
strftime( tmpbuf, 199, "%Y-%m-%d %H-%M-%S", pt );
else
{
std::stringstream strs;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 652 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 KiB

After

Width:  |  Height:  |  Size: 805 KiB

View file

@ -151,7 +151,7 @@ namespace command_line
}
template<typename F>
bool handle_error_helper(const boost::program_options::options_description& desc, F parser)
bool handle_error_helper(const boost::program_options::options_description& desc, std::string& err, F parser)
{
try
{
@ -159,6 +159,7 @@ namespace command_line
}
catch (std::exception& e)
{
err = e.what();
std::cerr << "Failed to parse arguments: " << e.what() << std::endl;
std::cerr << desc << std::endl;
return false;
@ -171,6 +172,13 @@ namespace command_line
}
}
template<typename F>
bool handle_error_helper(const boost::program_options::options_description& desc, F parser)
{
std::string stub_err;
return handle_error_helper(desc, stub_err, parser);
}
template<typename T, bool required>
bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg)
{

View file

@ -143,9 +143,10 @@ namespace tools
else
{
int res = 0;
//MDBX_txn_flags_t flags = MDBX_txn_flags_t();
unsigned int flags = 0;
if (read_only)
flags += MDBX_RDONLY;
flags = MDBX_RDONLY;//flags = MDBX_TXN_RDONLY;
//don't use parent tx in write transactions if parent tx was read-only (restriction in mdbx)
//see "Nested transactions: Max 1 child, write txns only, no writemap"
@ -340,7 +341,9 @@ namespace tools
data[0].iov_base = (void*)v;
data[0].iov_len = vs;
res = mdbx_put(get_current_tx(), static_cast<MDBX_dbi>(h), &key, data, 0);
//MDBX_put_flags_t flags = MDBX_put_flags_t();
unsigned flags = 0;
res = mdbx_put(get_current_tx(), static_cast<MDBX_dbi>(h), &key, data, flags);
CHECK_AND_ASSERT_MESS_MDBX_DB(res, false, "Unable to mdbx_put");
return true;
}

View file

@ -70,8 +70,7 @@ namespace currency
iv = *((crypto::chacha8_iv*)&pass_hash);
crypto::chacha8(scr_data, src_length, key, iv, (char*)dst_data);
}
//-----------------------------------------------------------------
std::string account_base::get_seed_phrase(const std::string& password) const
{
if (m_keys_seed_binary.empty())

View file

@ -211,7 +211,7 @@
#define MINER_CONFIG_FILENAME "miner_conf.json"
#define GUI_SECURE_CONFIG_FILENAME "gui_secure_conf.bin"
#define GUI_CONFIG_FILENAME "gui_settings.json"
#define GUI_INTERNAL_CONFIG "gui_internal_config.bin"
#define GUI_INTERNAL_CONFIG2 "gui_internal_config.json"

View file

@ -914,7 +914,8 @@ namespace currency
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with \r\nm_total_height=" << arg.total_height
<< "\r\nm_start_height=" << arg.start_height
<< "\r\nm_block_ids.size()=" << arg.m_block_ids.size());
//m_p2p->drop_connection(context);
m_p2p->drop_connection(context);
m_p2p->add_ip_fail(context.m_remote_ip);
}
BOOST_FOREACH(auto& bl_details, arg.m_block_ids)

View file

@ -45,10 +45,19 @@
<true/>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>ZanoApp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>zano</string>
</array>
</dict>
</array>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 109 KiB

View file

@ -387,9 +387,9 @@ void MainWindow::changeEvent(QEvent *e)
bool MainWindow::store_app_config()
{
TRY_ENTRY();
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG;
LOG_PRINT_L0("storing gui internal config from " << conf_path);
CHECK_AND_ASSERT_MES(tools::serialize_obj_to_file(m_config, conf_path), false, "failed to store gui internal config");
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG2;
LOG_PRINT_L0("storing gui internal config to " << conf_path);
CHECK_AND_ASSERT_MES(epee::serialization::store_t_to_json_file(m_config, conf_path), false, "failed to store gui internal config");
return true;
CATCH_ENTRY2(false);
}
@ -397,9 +397,9 @@ bool MainWindow::store_app_config()
bool MainWindow::load_app_config()
{
TRY_ENTRY();
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG;
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG2;
LOG_PRINT_L0("loading gui internal config from " << conf_path);
bool r = tools::unserialize_obj_from_file(m_config, conf_path);
bool r = epee::serialization::load_t_from_json_file(m_config, conf_path);
LOG_PRINT_L0("gui internal config " << (r ? "loaded ok" : "was not loaded"));
return r;
CATCH_ENTRY2(false);
@ -643,6 +643,7 @@ bool MainWindow::show_inital()
restore_pos(true);
else
{
m_config = AUTO_VAL_INIT(m_config);
this->show();
QSize sz;
sz.setHeight(770);
@ -651,6 +652,7 @@ bool MainWindow::show_inital()
store_window_pos();
m_config.is_maximazed = false;
m_config.is_showed = true;
m_config.disable_notifications = false;
}
return true;
CATCH_ENTRY2(false);
@ -727,14 +729,26 @@ void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, c
bool MainWindow::init_backend(int argc, char* argv[])
{
TRY_ENTRY();
if (!m_backend.init_command_line(argc, argv))
std::string command_line_fail_details;
if (!m_backend.init_command_line(argc, argv, command_line_fail_details))
{
this->show_msg_box(command_line_fail_details);
return false;
}
if (!init_window())
{
this->show_msg_box("Failed to main screen launch, check logs for the more detais.");
return false;
}
if (!m_backend.init(this))
{
this->show_msg_box("Failed to initialize backend, check debug logs for more details.");
return false;
}
if (m_backend.is_qt_logs_enabled())
{
@ -811,8 +825,25 @@ bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, l
CATCH_ENTRY2(false);
}
bool MainWindow::get_is_disabled_notifications()
{
return m_config.disable_notifications;
}
bool MainWindow::set_is_disabled_notifications(const bool& param)
{
m_config.disable_notifications = param;
return m_config.disable_notifications;
}
QString MainWindow::export_wallet_history(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::export_wallet_info, ewi);
PREPARE_RESPONSE(view::api_response, ar);
ar.error_code = m_backend.export_wallet_history(ewi);
return MAKE_RESPONSE(ar);
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}
bool MainWindow::update_wallets_info(const view::wallets_summary_info& wsi)
{
TRY_ENTRY();
@ -834,6 +865,10 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
LOG_PRINT_L0(get_wallet_log_prefix(tei.wallet_id) + "SENDING SIGNAL -> [money_transfer]" << std::endl << json_str);
//this->money_transfer(json_str.c_str());
QMetaObject::invokeMethod(this, "money_transfer", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str()));
if (m_config.disable_notifications)
return true;
if (!m_tray_icon)
return true;
if (!tei.ti.is_income)
@ -852,7 +887,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
return true;
}
auto amount_str = currency::print_money(tei.ti.amount);
auto amount_str = currency::print_money_brief(tei.ti.amount);
std::string title, msg;
if (tei.ti.height == 0) // unconfirmed trx
{
@ -869,6 +904,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
else if (tei.ti.unlock_time)
msg += m_localization[localization_id_locked];
show_notification(title, msg);
return true;

View file

@ -8,6 +8,7 @@
#include <QWebChannel>
#include "wallet/view_iface.h"
#include "serialization/keyvalue_helper_structs.h"
#ifndef Q_MOC_RUN
#include "wallet/wallets_manager.h"
@ -60,10 +61,20 @@ public:
struct app_config
{
std::pair<int64_t, int64_t> m_window_position;
std::pair<int64_t, int64_t> m_window_size;
epee::kvserializable_pair<int64_t, int64_t> m_window_position;
epee::kvserializable_pair<int64_t, int64_t> m_window_size;
bool is_maximazed;
bool is_showed;
bool disable_notifications;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_window_position)
KV_SERIALIZE(m_window_size)
KV_SERIALIZE(is_maximazed)
KV_SERIALIZE(is_showed)
KV_SERIALIZE(disable_notifications)
END_KV_SERIALIZE_MAP()
};
protected slots:
@ -150,6 +161,10 @@ public:
QString get_default_fee();
QString get_options();
void bool_toggle_icon(const QString& param);
bool get_is_disabled_notifications();
bool set_is_disabled_notifications(const bool& param);
QString export_wallet_history(const QString& param);
QString get_log_file();
QString check_available_sources(const QString& param);
QString open_url_in_browser(const QString& param);
@ -176,6 +191,7 @@ signals:
void do_dispatch(const QString status, const QString params); //general function
void on_core_event(const QString method_name); //general function
void set_options(const QString str); //general function
void get_wallet_name();
private:
//-------------------- i_core_event_handler --------------------
@ -254,7 +270,7 @@ private:
enum localization_string_indices
{
// order is surprizingly important here! (see also updateLocalisation in AppController.js)
// order is surprisingly important here! (see also updateLocalisation in AppController.js)
localization_id_quit = 0,
localization_id_is_received,
localization_id_is_confirmed,

View file

@ -0,0 +1,18 @@
#include "urleventfilter.h"
#include <QMessageBox>
bool URLEventFilter::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
if(!fileEvent->url().isEmpty())
{
QMessageBox msg;
msg.setText(fileEvent->url().toString());
msg.exec();
}
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
};

View file

@ -0,0 +1,12 @@
#include <QObject>
#include <QFileOpenEvent>
#include <QDebug>
class URLEventFilter : public QObject
{
Q_OBJECT
public:
URLEventFilter() : QObject(){};
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
};

@ -1 +1 @@
Subproject commit b028252d30a32e80c12fa890c306d3c5842e937a
Subproject commit d32d0f9f239589b0cdf0ba674991124c231734de

View file

@ -12,7 +12,9 @@
//#include "qtlogger.h"
#include "include_base_utils.h"
#include "currency_core/currency_config.h"
#ifdef Q_OS_DARWIN
#include "application/urleventfilter.h"
#endif
int main(int argc, char *argv[])
{
@ -26,6 +28,9 @@ int main(int argc, char *argv[])
// See http://crbug.com/436603.
// _set_FMA3_enable(0);
//#endif // ARCH_CPU_X86_64 && _MSC_VER <= 1800
if(argc > 1)
std::cout << argv[1] << std::endl;
#ifdef _MSC_VER
#ifdef _WIN64
@ -61,12 +66,18 @@ 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))
{
static_cast<view::i_view*>(&viewer)->show_msg_box("Failed to initialize backend, check debug logs for more details.");
return 1;
}
app.installNativeEventFilter(&viewer);
viewer.setWindowTitle(CURRENCY_NAME_BASE);
viewer.show_inital();

View file

@ -81,7 +81,8 @@ namespace nodetool
m_last_stat_request_time{},
m_use_only_priority_peers(false),
m_peer_livetime{},
m_debug_requests_enabled(false)
m_debug_requests_enabled(false),
m_ip_auto_blocking_enabled(false)
{}
static void init_options(boost::program_options::options_description& desc);
@ -215,6 +216,8 @@ namespace nodetool
bool urgent_alert_worker();
bool critical_alert_worker();
bool remove_dead_connections();
bool is_ip_good_for_adding_to_peerlist(uint32_t adress);
bool is_ip_in_blacklist(uint32_t adress);
//debug functions
@ -245,6 +248,7 @@ namespace nodetool
bool m_hide_my_port;
bool m_offline_mode;
bool m_debug_requests_enabled;
bool m_ip_auto_blocking_enabled;
uint64_t m_startup_time;

View file

@ -26,18 +26,19 @@ namespace nodetool
namespace
{
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node = {"add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open"};
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node = {"add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open"};
const command_line::arg_descriptor<bool> arg_p2p_use_only_priority_nodes = {"use-only-priority-nodes", "Try to connect only to priority nodes"};
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
const command_line::arg_descriptor<bool> arg_p2p_offline_mode = { "offline-mode", "Don't connect to any node and reject any connections", false, true };
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs = { "disable-debug-p2p-requests", "Disable p2p debug requests", false, true };
}
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
const command_line::arg_descriptor<bool> arg_p2p_offline_mode = { "offline-mode", "Don't connect to any node and reject any connections", false, true };
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs = { "disable-debug-p2p-requests", "Disable p2p debug requests", false, true };
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking = { "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 0", 0, false };
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@ -53,7 +54,8 @@ namespace nodetool
command_line::add_arg(desc, arg_p2p_hide_my_port);
command_line::add_arg(desc, arg_p2p_offline_mode);
command_line::add_arg(desc, arg_p2p_disable_debug_reqs);
command_line::add_arg(desc, arg_p2p_use_only_priority_nodes);
command_line::add_arg(desc, arg_p2p_use_only_priority_nodes);
command_line::add_arg(desc, arg_p2p_ip_auto_blocking);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@ -65,7 +67,14 @@ namespace nodetool
CHECK_AND_ASSERT_MES(r, false, "Failed to parse P2P_MAINTAINERS_PUB_KEY = " << P2P_MAINTAINERS_PUB_KEY);
std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME;
tools::unserialize_obj_from_file(*this, state_file_path);
boost::system::error_code ec = AUTO_VAL_INIT(ec);
std::time_t last_update_time = boost::filesystem::last_write_time(state_file_path, ec);
//let's assume that if p2p peer list file stored more then 2 weeks ago,
//then it outdated and we need to fetch peerlist from seed nodes
if (!ec && time(nullptr) - last_update_time < 86400 * 14)
{
tools::unserialize_obj_from_file(*this, state_file_path);
}
//always use new id, to be able differ cloned computers
m_config.m_peer_id = crypto::rand<uint64_t>();
@ -100,21 +109,39 @@ namespace nodetool
if (m_offline_mode)
return false;
//@#@ temporary workaround
return true;
#if 0
if (!m_ip_auto_blocking_enabled)
return true;
return !is_ip_in_blacklist(addr);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_ip_good_for_adding_to_peerlist(uint32_t addr)
{
if (m_offline_mode)
return false;
// even if IP auto blocking is disabled, bad peers should not be added to peerlists and be shared with other nodes
return !is_ip_in_blacklist(addr);
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr)
{
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
auto it = m_blocked_ips.find(addr);
if(it == m_blocked_ips.end())
return true;
if(time(nullptr) - it->second > P2P_IP_BLOCKTIME )
if (it == m_blocked_ips.end())
return false;
if (time(nullptr) - it->second > P2P_IP_BLOCKTIME)
{
m_blocked_ips.erase(it);
LOG_PRINT_CYAN("Ip " << string_tools::get_ip_string_from_int32(addr) << "is unblocked.", LOG_LEVEL_0);
return true;
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(addr) << " is unblocked due to blocking expiration.", LOG_LEVEL_0);
return false;
}
return false;
#endif
return true;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
@ -122,7 +149,8 @@ namespace nodetool
{
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
m_blocked_ips[addr] = time(nullptr);
LOG_PRINT_CYAN("Ip " << string_tools::get_ip_string_from_int32(addr) << " blocked.", LOG_LEVEL_0);
m_peerlist.remove_peers_by_ip_from_all(addr);
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(addr) << " blocked and removed from peerlist", LOG_LEVEL_0);
return true;
}
//-----------------------------------------------------------------------------------
@ -138,6 +166,10 @@ namespace nodetool
it->second = P2P_IP_FAILS_BEFOR_BLOCK/2;
block_ip(address);
}
else
{
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(address) << ": fail recorded, total fails count: " << fails, LOG_LEVEL_2);
}
return true;
}
//-----------------------------------------------------------------------------------
@ -162,6 +194,9 @@ namespace nodetool
m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip);
m_offline_mode = command_line::get_arg(vm, arg_p2p_offline_mode);
m_debug_requests_enabled = !command_line::get_arg(vm, arg_p2p_disable_debug_reqs);
m_ip_auto_blocking_enabled = (command_line::get_arg(vm, arg_p2p_ip_auto_blocking) != 0);
LOG_PRINT_L0("p2p peers auto-blocking is " << (m_ip_auto_blocking_enabled ? "enabled" : "disabled"));
if (m_offline_mode)
{
@ -679,7 +714,6 @@ namespace nodetool
<< string_tools::get_ip_string_from_int32(na.ip)
<< ":" << string_tools::num_to_string_fast(na.port)
/*<< ", try " << try_count*/);
//m_peerlist.set_peer_unreachable(pe);
return false;
}
peerid_type pi = AUTO_VAL_INIT(pi);
@ -701,12 +735,15 @@ namespace nodetool
return true;
}
peerlist_entry pe_local = AUTO_VAL_INIT(pe_local);
pe_local.adr = na;
pe_local.id = pi;
time(&pe_local.last_seen);
m_peerlist.append_with_peer_white(pe_local);
//update last seen and push it to peerlist manager
if (is_ip_good_for_adding_to_peerlist(na.ip)) // additional check to avoid IP shown up in peers in the case of non-blocking incoming connections
{
//update last seen and push it to peerlist manager
peerlist_entry pe_local = AUTO_VAL_INIT(pe_local);
pe_local.adr = na;
pe_local.id = pi;
time(&pe_local.last_seen);
m_peerlist.append_with_peer_white(pe_local);
}
LOG_PRINT_CC_GREEN(con, "CONNECTION HANDSHAKED OK with peer " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port), LOG_LEVEL_2);
return true;
@ -1373,7 +1410,8 @@ namespace nodetool
//associate peer_id with this connection
context.peer_id = arg.node_data.peer_id;
if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port)
if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port
&& is_ip_good_for_adding_to_peerlist(context.m_remote_ip))
{
peerid_type peer_id_l = arg.node_data.peer_id;
uint32_t port_l = arg.node_data.my_port;

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2019 Zano Project
// Copyright (c) 2014-2021 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -11,8 +11,6 @@
#include <map>
#include <iterator>
#include <boost/foreach.hpp>
//#include <boost/bimap.hpp>
//#include <boost/bimap/multiset_of.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/version.hpp>
@ -55,10 +53,10 @@ namespace nodetool
bool append_with_peer_gray(const peerlist_entry& pr);
bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
bool set_peer_unreachable(const peerlist_entry& pr);
bool is_ip_allowed(uint32_t ip);
void trim_white_peerlist();
void trim_gray_peerlist();
bool remove_peers_by_ip_from_all(const uint32_t ip);
private:
@ -110,17 +108,6 @@ namespace nodetool
>
> peers_indexed;
typedef boost::multi_index_container<
peerlist_entry,
boost::multi_index::indexed_by<
// access by peerlist_entry::id<
boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >,
// access by peerlist_entry::net_adress
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
// sort by peerlist_entry::last_seen<
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,time_t,&peerlist_entry::last_seen> >
>
> peers_indexed_old;
public:
template <class Archive, class t_version_type>
@ -134,9 +121,7 @@ namespace nodetool
ar & m_peers_gray;
}
private:
bool peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi);
private:
friend class boost::serialization::access;
epee::critical_section m_peerlist_lock;
std::string m_config_folder;
@ -188,21 +173,6 @@ namespace nodetool
return true;
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi)
{
for(auto x: pio)
{
auto by_addr_it = pi.get<by_addr>().find(x.adr);
if(by_addr_it == pi.get<by_addr>().end())
{
pi.insert(x);
}
}
return true;
}
//--------------------------------------------------------------------------------------------------
inline void peerlist_manager::trim_white_peerlist()
{
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -393,6 +363,33 @@ namespace nodetool
return true;
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::remove_peers_by_ip_from_all(const uint32_t ip)
{
TRY_ENTRY();
CRITICAL_REGION_LOCAL(m_peerlist_lock);
for (auto it = m_peers_white.begin(); it != m_peers_white.end();)
{
if (it->adr.ip == ip)
it = m_peers_white.erase(it);
else
++it;
}
for (auto it = m_peers_gray.begin(); it != m_peers_gray.end();)
{
if (it->adr.ip == ip)
it = m_peers_gray.erase(it);
else
++it;
}
return true;
CATCH_ENTRY_L0("peerlist_manager::remove_peers_by_ip_from_all()", false);
}
//--------------------------------------------------------------------------------------------------
}
BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)

View file

@ -228,6 +228,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), "sign_transfer <unsgined_tx_file> <signed_tx_file> - sign unsigned tx from a watch-only wallet");
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), "submit_transfer <signed_tx_file> - broadcast signed tx");
m_cmd_binder.set_handler("export_history", boost::bind(&simple_wallet::submit_transfer, this, _1), "Export transaction history in CSV file");
}
//----------------------------------------------------------------------------------------------------
simple_wallet::~simple_wallet()
@ -798,12 +799,7 @@ bool simple_wallet::list_recent_transfers(const std::vector<std::string>& args)
std::string wti_to_text_line(const tools::wallet_public::wallet_transfer_info& wti)
{
stringstream ss;
ss << (wti.is_income ? "[INC]" : "[OUT]") << "\t"
<< epee::misc_utils::get_time_str(wti.timestamp) << "\t"
<< print_money(wti.amount) << "\t"
<< print_money(wti.fee) << "\t"
<< wti.remote_addresses << "\t"
<< wti.comment << "\t";
return ss.str();
}
//----------------------------------------------------------------------------------------------------
@ -811,58 +807,37 @@ bool simple_wallet::export_recent_transfers(const std::vector<std::string>& args
{
bool export_to_json = true;
bool ignore_pos = false;
if (args.size())
{
if (args[0] == "json")
export_to_json = true;
else if (args[0] == "txt")
export_to_json = false;
}
if (args.size() > 1)
{
if (args[1] == "ignore-pos")
ignore_pos = true;
}
std::vector<tools::wallet_public::wallet_transfer_info> unconfirmed;
std::vector<tools::wallet_public::wallet_transfer_info> recent;
uint64_t total = 0;
uint64_t last_index = 0;
m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false);
m_wallet->get_unconfirmed_transfers(unconfirmed, false);
//workaround for missed fee
stringstream ss;
LOG_PRINT_GREEN("Generating text....", LOG_LEVEL_0);
ss << "Unconfirmed transfers: " << ENDL;
for (auto & wti : unconfirmed)
std::string format = "csv";
if (args.size() > 0)
{
if(ignore_pos && wti.is_mining)
continue;
if (!wti.fee)
wti.fee = currency::get_tx_fee(wti.tx);
if(export_to_json)
ss << epee::serialization::store_t_to_json(wti) << ENDL;
if (args[0] == "json" || args[0] == "csv" || args[0] == "text")
{
format = args[0];
}
else
ss << wti_to_text_line(wti) << ENDL;
{
fail_msg_writer() << "Unknown format: \"" << args[0] << "\", only \"csv\"(default), \"json\" and \"text\" supported";
}
}
ss << "Recent transfers: " << ENDL;
for (auto & wti : recent)
try {
boost::filesystem::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(log_space::log_singletone::get_default_log_folder() + "/wallet_recent_transfers.txt", std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
m_wallet->export_transaction_history(fstream, format, !ignore_pos);
fstream.close();
}
catch (...)
{
if (ignore_pos && wti.is_mining)
continue;
if (!wti.fee)
wti.fee = currency::get_tx_fee(wti.tx);
if (export_to_json)
ss << epee::serialization::store_t_to_json(wti) << ENDL;
else
ss << wti_to_text_line(wti) << ENDL;
success_msg_writer() << "Failed";
return false;
}
LOG_PRINT_GREEN("Storing text to wallet_recent_transfers.txt....", LOG_LEVEL_0);
file_io_utils::save_string_to_file(log_space::log_singletone::get_default_log_folder() + "/wallet_recent_transfers.txt", ss.str());
LOG_PRINT_GREEN("Done", LOG_LEVEL_0);
return true;
}
//----------------------------------------------------------------------------------------------------

View file

@ -201,7 +201,8 @@ namespace plain_wallet
args[1] = const_cast<char*>(argss_1.c_str());
args[2] = const_cast<char*>(argss_2.c_str());
args[3] = nullptr;
if (!(ptr->gwm.init_command_line(3, args) && ptr->gwm.init(nullptr)))
std::string command_line_fail_details;
if (!(ptr->gwm.init_command_line(3, args, command_line_fail_details) && ptr->gwm.init(nullptr)))
{
LOG_ERROR("Failed to init wallets_manager");
return GENERAL_INTERNAL_ERRROR_INIT;

View file

@ -284,6 +284,20 @@ public:
END_KV_SERIALIZE_MAP()
};
struct export_wallet_info
{
uint64_t wallet_id;
bool include_pos_transactions;
std::string path;
std::string format;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(wallet_id)
KV_SERIALIZE(include_pos_transactions)
KV_SERIALIZE(path)
KV_SERIALIZE(format)
END_KV_SERIALIZE_MAP()
};
struct response_mining_estimate
{

View file

@ -3254,6 +3254,87 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
total = m_transfer_history.size();
}
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 << print_money(wti.amount) << ",";
ss << "\"" << wti.comment << "\",";
ss << "[";
std::copy(wti.remote_addresses.begin(), wti.remote_addresses.end(), std::ostream_iterator<std::string>(ss, " "));
ss << "]" << ",";
ss << wti.tx_hash << ",";
ss << wti.height << ",";
ss << wti.unlock_time << ",";
ss << wti.tx_blob_size << ",";
ss << epee::string_tools::buff_to_hex_nodelimer(wti.payment_id) << ",";
ss << "[";
std::copy(wti.recipients_aliases.begin(), wti.recipients_aliases.end(), std::ostream_iterator<std::string>(ss, " "));
ss << "]" << ",";
ss << (wti.is_income ? "in" : "out") << ",";
ss << (wti.is_service ? "[SERVICE]" : "") << (wti.is_mixing ? "[MIXINS]" : "") << (wti.is_mining ? "[MINING]" : "") << ",";
ss << wti.tx_type << ",";
ss << wti.fee << ENDL;
};
void wallet2::wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index)
{
ss << (wti.is_income ? "[INC]" : "[OUT]") << "\t"
<< epee::misc_utils::get_time_str(wti.timestamp) << "\t"
<< print_money(wti.amount) << "\t"
<< print_money(wti.fee) << "\t"
<< wti.remote_addresses << "\t"
<< wti.comment << ENDL;
};
void wallet2::wti_to_json_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index)
{
ss << epee::serialization::store_t_to_json(wti, 4) << ",";
};
//----------------------------------------------------------------------------------------------------
void wallet2::export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions)
{
//typedef int(*t_somefunc)(int, int);
typedef void(*playout_cb_type)(std::ostream&, const wallet_public::wallet_transfer_info&, size_t);
playout_cb_type cb_csv = &wallet2::wti_to_csv_entry;
playout_cb_type cb_json = &wallet2::wti_to_json_line;
playout_cb_type cb_plain_text = &wallet2::wti_to_txt_line;
playout_cb_type cb = cb_csv;
if (format == "json")
{
ss << "{ \"history\": [";
cb = cb_json;
}
else if (format == "text")
{
cb = cb_plain_text;
}
else
{
//csv by default
ss << "N, Date, Amount, Comment, Address, ID, Height, Unlock timestamp, Tx size, Alias, In/Out, Flags, Type, Fee" << ENDL;
}
enum_container(m_transfer_history.begin(), m_transfer_history.end(), [&](wallet_public::wallet_transfer_info& wti, size_t index) {
if (!include_pos_transactions)
{
if (currency::is_coinbase(wti.tx))
return true;
}
cb(ss, wti, index);
return true;
});
if (format == "json")
{
ss << "{}]}";
}
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id)

View file

@ -861,6 +861,8 @@ namespace tools
uint64_t get_wallet_file_size()const;
void set_use_deffered_global_outputs(bool use);
construct_tx_param get_default_construct_tx_param_inital();
void export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions = true);
/*
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
@ -872,7 +874,6 @@ namespace tools
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin, currency::transaction& result_tx);
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin);
bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id);
private:
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
@ -1006,6 +1007,10 @@ private:
void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra);
void remove_transfer_from_amount_gindex_map(uint64_t tid);
static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
static void wti_to_json_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
currency::account_base m_account;
bool m_watch_only;
std::string m_log_prefix; // part of pub address, prefix for logging functions

View file

@ -56,7 +56,11 @@ namespace tools
command_line::add_arg(desc, arg_deaf_mode);
}
//------------------------------------------------------------------------------------------------------------------------------
wallet_rpc_server::wallet_rpc_server(wallet2& w):m_wallet(w), m_do_mint(false), m_deaf(false)
wallet_rpc_server::wallet_rpc_server(wallet2& w)
: m_wallet(w)
, m_do_mint(false)
, m_deaf(false)
, m_last_wallet_store_height(0)
{}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address)
@ -309,7 +313,7 @@ namespace tools
else
{
//put it to attachments
ctp.attachments.insert(ctp.extra.end(), req.service_entries.begin(), req.service_entries.end());
ctp.attachments.insert(ctp.attachments.end(), req.service_entries.begin(), req.service_entries.end());
}
bool wrap = false;
std::vector<currency::tx_destination_entry>& dsts = ctp.dsts;
@ -397,7 +401,7 @@ namespace tools
currency::finalized_tx result = AUTO_VAL_INIT(result);
std::string unsigned_tx_blob_str;
ctp.fee = req.fee;
ctp.fake_outputs_count = 0;
ctp.fake_outputs_count = req.mixin;
m_wallet.transfer(ctp, result, true, &unsigned_tx_blob_str);
if (m_wallet.is_watch_only())
{

View file

@ -152,7 +152,7 @@ bool wallets_manager::do_exception_safe_call(guarded_code_t guarded_code, error_
}
bool wallets_manager::init_command_line(int argc, char* argv[])
bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fail_message)
{
TRY_ENTRY();
po::options_description desc_cmd_only("Command line options");
@ -197,9 +197,8 @@ bool wallets_manager::init_command_line(int argc, char* argv[])
po::options_description desc_options("Allowed options");
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
bool coomand_line_parsed = command_line::handle_error_helper(desc_options, [&]()
std::string err_str;
bool command_line_parsed = command_line::handle_error_helper(desc_options, err_str, [&]()
{
po::store(po::parse_command_line(argc, argv, desc_options), m_vm);
@ -230,23 +229,29 @@ bool wallets_manager::init_command_line(int argc, char* argv[])
return true;
});
if (!coomand_line_parsed)
if (!command_line_parsed)
{
std::stringstream ss;
ss << "Command line has wrong arguments: " << std::endl;
for (int i = 0; i != argc; i++)
ss << "[" << i << "] " << argv[i] << std::endl;
std::cerr << ss.str() << std::endl << std::flush;
fail_message = "Error parsing arguments.\n";
fail_message += err_str + "\n";
std::stringstream s;
desc_options.print(s);
fail_message += s.str();
return false;
}
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);
}
void terminate_handler_func()
{
LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack
@ -798,6 +803,24 @@ std::string wallets_manager::get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INF
}
std::string wallets_manager::export_wallet_history(const view::export_wallet_info& ewi)
{
GET_WALLET_OPT_BY_ID(ewi.wallet_id, wo);
try {
boost::filesystem::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(ewi.path, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
wo.w->get()->export_transaction_history(fstream, ewi.format, ewi.include_pos_transactions);
fstream.close();
}
catch (...)
{
return API_RETURN_CODE_FAIL;
}
return API_RETURN_CODE_OK;
}
uint64_t wallets_manager::get_default_fee()
{
return TX_DEFAULT_FEE;
@ -1802,7 +1825,10 @@ void wallets_manager::on_transfer2(size_t wallet_id, const tools::wallet_public:
GET_WALLET_OPTIONS_BY_ID_VOID_RET(wallet_id, w);
tei.is_wallet_in_sync_process = w.long_refresh_in_progress;
m_pview->money_transfer(tei);
if (!(w.w->get()->is_watch_only()))
{
m_pview->money_transfer(tei);
}
}
void wallets_manager::on_pos_block_found(size_t wallet_id, const currency::block& b)
{

View file

@ -89,7 +89,7 @@ public:
wallets_manager();
~wallets_manager();
bool init_command_line(int argc, char* argv[]);
bool init_command_line(int argc, char* argv[], std::string& fail_message);
bool init(view::i_view* pview_handler);
bool start();
bool stop();
@ -139,6 +139,7 @@ public:
std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
std::string get_fav_offers(const std::list<bc_services::offer_id>& hashes, const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res);
std::string export_wallet_history(const view::export_wallet_info& ewi);
uint64_t get_default_fee();
std::string get_mining_estimate(uint64_t amuont_coins,
uint64_t time,

View file

@ -2053,6 +2053,25 @@ bool check_ring_signature_at_gen_time(const std::vector<test_event_entry>& event
return true;
}
bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, currency::core& c)
{
std::shared_ptr<const currency::transaction_chain_entry> ptce = c.get_blockchain_storage().get_tx_chain_entry(tx_id);
if (!ptce)
return false;
for (size_t i = 0; i < ptce->tx.vin.size(); ++i)
{
auto& input = ptce->tx.vin[i];
if (input.type() == typeid(txin_to_key))
{
auto& intk = boost::get<txin_to_key>(input);
CHECK_AND_ASSERT_MES(intk.key_offsets.size() == mixin + 1, false, "for input #" << i << " mixin count is " << intk.key_offsets.size() - 1 << ", expected is " << mixin);
}
}
return true;
}
//------------------------------------------------------------------------------
void test_chain_unit_base::register_callback(const std::string& cb_name, verify_callback cb)

View file

@ -679,6 +679,7 @@ bool generate_pos_block_with_given_coinstake(test_generator& generator, const st
bool check_ring_signature_at_gen_time(const std::vector<test_event_entry>& events, const crypto::hash& last_block_id, const currency::txin_to_key& in_t_k,
const crypto::hash& hash_for_sig, const std::vector<crypto::signature> &sig);
bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, currency::core& c);
//--------------------------------------------------------------------------
template<class t_test_class>

View file

@ -867,6 +867,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
GENERATE_AND_PLAY(wallet_rpc_integrated_address_transfer);
GENERATE_AND_PLAY(wallet_rpc_transfer);
GENERATE_AND_PLAY(wallet_chain_switch_with_spending_the_same_ki);
GENERATE_AND_PLAY(wallet_sending_to_integrated_address);

View file

@ -148,6 +148,7 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind
alice_wlt->get_payments(payment_id, payments);
CHECK_AND_ASSERT_MES(payments.size() == 1, false, "Invalid payments count: " << payments.size());
CHECK_AND_ASSERT_MES(payments.front().m_amount == MK_TEST_COINS(3), false, "Invalid payment");
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(0, payments.front().m_tx_hash, c), false, ""); // make sure number of decoys is correct
// 3. standard address + invalid external payment id => fail
@ -181,9 +182,127 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind
alice_wlt->get_payments(payment_id, payments);
CHECK_AND_ASSERT_MES(payments.size() == 1, false, "Invalid payments count: " << payments.size());
CHECK_AND_ASSERT_MES(payments.front().m_amount == MK_TEST_COINS(7), false, "Invalid payment");
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(0, payments.front().m_tx_hash, c), false, ""); // make sure number of decoys is correct
return true;
}
//------------------------------------------------------------------------------
wallet_rpc_transfer::wallet_rpc_transfer()
{
REGISTER_CALLBACK_METHOD(wallet_rpc_transfer, configure_core);
REGISTER_CALLBACK_METHOD(wallet_rpc_transfer, c1);
}
bool wallet_rpc_transfer::generate(std::vector<test_event_entry>& events) const
{
m_accounts.resize(TOTAL_ACCS_COUNT);
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate();
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate();
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
DO_CALLBACK(events, "configure_core");
set_hard_fork_heights_to_generator(generator);
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 6);
DO_CALLBACK(events, "c1");
return true;
}
bool wallet_rpc_transfer::configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
pc.hard_fork_01_starts_after_height = 1;
pc.hard_fork_02_starts_after_height = 1;
pc.hard_fork_03_starts_after_height = 1;
c.get_blockchain_storage().set_core_runtime_config(pc);
return true;
}
bool wallet_rpc_transfer::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
bool r = false;
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
miner_wlt->refresh();
// wallet RPC server
tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt);
epee::json_rpc::error je;
tools::wallet_rpc_server::connection_context ctx;
// 1. Check non-zero mixin and default settings
tools::wallet_public::COMMAND_RPC_TRANSFER::request req = AUTO_VAL_INIT(req);
req.fee = TESTS_DEFAULT_FEE;
req.mixin = 2;
tools::wallet_public::transfer_destination tds = AUTO_VAL_INIT(tds);
tds.address = m_accounts[ALICE_ACC_IDX].get_public_address_str();
tds.amount = MK_TEST_COINS(3);
req.destinations.push_back(tds);
tools::wallet_public::COMMAND_RPC_TRANSFER::response res = AUTO_VAL_INIT(res);
r = miner_wlt_rpc.on_transfer(req, res, je, ctx);
CHECK_AND_ASSERT_MES(r, false, "RPC call failed, code: " << je.code << ", msg: " << je.message);
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count());
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count());
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, tds.amount), false, "");
// check the transfer has been received
tools::wallet2::transfer_details td = AUTO_VAL_INIT(td);
CHECK_AND_ASSERT_MES(alice_wlt->get_transfer_info_by_index(0, td), false, "");
CHECK_AND_ASSERT_MES(td.amount() == MK_TEST_COINS(3), false, "Invalid payment");
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(2, td.tx_hash(), c), false, "");
// make sure tx_received is set by default, but tx_payer is not
std::shared_ptr<const transaction_chain_entry> pche = c.get_blockchain_storage().get_tx_chain_entry(td.tx_hash());
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_receiver>(pche->tx.extra) == 1, false, "tx_receiver: incorrect count of items");
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_payer>(pche->tx.extra) == 0, false, "tx_payer: incorrect count of items");
// 2. check tx_receiver and tx_payer non-default
req.mixin = 1;
req.hide_receiver = true;
req.push_payer = true;
tds.amount = MK_TEST_COINS(5);
req.destinations.clear();
req.destinations.push_back(tds);
res = AUTO_VAL_INIT(res);
r = miner_wlt_rpc.on_transfer(req, res, je, ctx);
CHECK_AND_ASSERT_MES(r, false, "RPC call failed, code: " << je.code << ", msg: " << je.message);
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count());
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count());
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(3 + 5)), false, "");
td = AUTO_VAL_INIT(td);
CHECK_AND_ASSERT_MES(alice_wlt->get_transfer_info_by_index(1, td), false, "");
CHECK_AND_ASSERT_MES(td.amount() == MK_TEST_COINS(5), false, "Invalid payment");
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(1, td.tx_hash(), c), false, "");
// make sure tx_received is set by default, but tx_payer is not
pche = c.get_blockchain_storage().get_tx_chain_entry(td.tx_hash());
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_receiver>(pche->tx.extra) == 0, false, "tx_receiver: incorrect count of items");
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_payer>(pche->tx.extra) == 1, false, "tx_payer: incorrect count of items");
return true;
}

View file

@ -21,3 +21,11 @@ struct wallet_rpc_integrated_address_transfer : public wallet_test
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
};
struct wallet_rpc_transfer : public wallet_test
{
wallet_rpc_transfer();
bool generate(std::vector<test_event_entry>& events) const;
bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
};

View file

@ -12,7 +12,7 @@ out_file_name=~/.local/share/applications/Zano.desktop
call_app()
{
pushd $script_dir
./Zano
./Zano "$@"
popd
exit
}
@ -25,17 +25,20 @@ create_desktop_icon()
rm -f $target_file_name
echo [Desktop Entry] | tee -a $target_file_name > /dev/null
echo Version=1.0 | tee -a $target_file_name > /dev/null
echo Name=My Application | tee -a $target_file_name > /dev/null
echo GenericName=My Application | tee -a $target_file_name > /dev/null
echo Comment=Doing some funny stuff | tee -a $target_file_name > /dev/null
echo Name=Zano | tee -a $target_file_name > /dev/null
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 | tee -a $target_file_name > /dev/null
echo Exec=$script_dir/Zano.sh %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
echo "MimeType=x-scheme-handler/zano;" | tee -a $target_file_name > /dev/null
}
create_desktop_icon $out_file_name
call_app
xdg-mime default Zano.desktop x-scheme-handler/zano
call_app "$@"

View file

@ -46,25 +46,18 @@ if [ $? -ne 0 ]; then
exit 1
fi
make -j1 daemon Zano;
make -j2 daemon simplewallet connectivity_tool
if [ $? -ne 0 ]; then
echo "Failed to make!"
exit 1
fi
make -j1 simplewallet;
make -j1 Zano
if [ $? -ne 0 ]; then
echo "Failed to make!"
exit 1
fi
make -j1 connectivity_tool;
if [ $? -ne 0 ]; then
echo "Failed to make!"
exit 1
fi
read version_str <<< $(./src/zanod --version | awk '/^Zano/ { print $2 }')
version_str=${version_str}

View file

@ -51,6 +51,8 @@ Root: HKCR; Subkey: "ZanoWalletDataKyesFile"; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "ZanoWalletDataFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\zano.exe,0"
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"
[Files]

View file

@ -52,6 +52,9 @@ Root: HKCR; Subkey: "ZanoWalletDataKyesFile"; ValueType: string; ValueName: "";
Root: HKCR; Subkey: "ZanoWalletDataFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Zano.exe,0"
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"
[Files]