Merge branch 'release'
This commit is contained in:
commit
6e6831c355
25 changed files with 339 additions and 344 deletions
|
|
@ -54,7 +54,7 @@ namespace epee {
|
|||
namespace net_utils {
|
||||
|
||||
struct i_connection_filter {
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress) = 0;
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress, bool is_incoming) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~i_connection_filter()
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ bool connection<t_protocol_handler>::start(bool is_income, bool is_multithreaded
|
|||
|
||||
LOG_PRINT_L3("[sock " << socket_.native_handle() << "] new connection, remote end_point: " << print_connection_context_short(context) << " local end_point: " << local_ep.address().to_string() << ':' << local_ep.port() << ", total sockets objects " << m_ref_sockets_count);
|
||||
|
||||
if(is_income && m_pfilter && !m_pfilter->is_remote_ip_allowed(context.m_remote_ip)) {
|
||||
if(is_income && m_pfilter && !m_pfilter->is_remote_ip_allowed(context.m_remote_ip, is_income)) {
|
||||
LOG_PRINT_L0("[sock " << socket_.native_handle() << "] ip denied " << string_tools::get_ip_string_from_int32(context.m_remote_ip) << ", shutdowning connection");
|
||||
close();
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#define SHORTENER_EVERY_100_BLOCKS_SIZE 144
|
||||
#define SHORTENER_EVERY_1000_BLOCKS_SIZE 144
|
||||
|
||||
static void exception_handler(){}
|
||||
//static void exception_handler(){}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -239,6 +239,7 @@
|
|||
|
||||
|
||||
#define P2P_NET_DATA_FILENAME "p2pstate.bin"
|
||||
#define P2P_MANUAL_CONFIG_FILENAME "p2p_manual_config.json"
|
||||
#define MINER_CONFIG_FILENAME "miner_conf.json"
|
||||
#define GUI_SECURE_CONFIG_FILENAME "gui_secure_conf.bin"
|
||||
#define GUI_CONFIG_FILENAME "gui_settings.json"
|
||||
|
|
|
|||
|
|
@ -925,9 +925,9 @@ namespace currency
|
|||
if (crc.is_hardfork_active_for_height(2, top_block_height))
|
||||
{
|
||||
// after hardfork 2
|
||||
tx_payer result = AUTO_VAL_INIT(result);
|
||||
result.acc_addr = addr;
|
||||
container.push_back(result);
|
||||
//tx_payer result = AUTO_VAL_INIT(result);
|
||||
//result.acc_addr = addr;
|
||||
//container.push_back(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -947,9 +947,9 @@ namespace currency
|
|||
if (crc.is_hardfork_active_for_height(2, top_block_height))
|
||||
{
|
||||
// after hardfork 2
|
||||
tx_receiver result = AUTO_VAL_INIT(result);
|
||||
result.acc_addr = addr;
|
||||
container.push_back(result);
|
||||
//tx_receiver result = AUTO_VAL_INIT(result);
|
||||
//result.acc_addr = addr;
|
||||
//container.push_back(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ namespace currency
|
|||
for(auto it = conn_map.rbegin(); it != conn_map.rend(); ++it)
|
||||
ss << it->second;
|
||||
|
||||
LOG_PRINT_L0("Connections (" << incoming_count << " in, " << outgoing_count << " out, " << incoming_count + outgoing_count << " total):" << ENDL << ss.str());
|
||||
LOG_PRINT_L0("Connections:" << ENDL << ss.str() << ENDL << "(" << incoming_count << " in, " << outgoing_count << " out, " << incoming_count + outgoing_count << " total)");
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ public:
|
|||
m_cmd_binder.set_handler("debug_remote_node_mode", boost::bind(&daemon_commands_handler::debug_remote_node_mode, this, ph::_1), "<ip-address> - If node got connected put node into 'debug mode' i.e. no sync process of other communication except ping responses, maintenance secrete key will be requested");
|
||||
m_cmd_binder.set_handler("full_db_cache_warmup", boost::bind(&daemon_commands_handler::full_db_cache_warmup, this, ph::_1), "(Experimental) Perform full DB loading to RAM cache(make sense only with big numbers passed to --db-cache-l2 option)");
|
||||
m_cmd_binder.set_handler("print_cache_state", boost::bind(&daemon_commands_handler::print_cache_state, this, ph::_1), "Print db l2 cache state");
|
||||
m_cmd_binder.set_handler("reload_p2p_manual_config", boost::bind(&daemon_commands_handler::reload_p2p_manual_config, this, ph::_1), "Reload manual p2p config from '" P2P_MANUAL_CONFIG_FILENAME "'");
|
||||
#ifdef _DEBUG
|
||||
m_cmd_binder.set_handler("debug_set_time_adj", boost::bind(&daemon_commands_handler::debug_set_time_adj, this, ph::_1), "DEBUG: set core time adjustment");
|
||||
#endif
|
||||
|
|
@ -226,10 +227,10 @@ private:
|
|||
std::map<uint32_t, time_t> blocklist;
|
||||
m_srv.get_ip_block_list(blocklist);
|
||||
std::stringstream ss;
|
||||
ss << "BLOCKED IPS:" << ENDL;
|
||||
ss << "AUTO BLOCKED IPs:" << ENDL << "ip block time" << ENDL;
|
||||
for (const auto& e : blocklist)
|
||||
{
|
||||
ss << string_tools::get_ip_string_from_int32(e.first) << ", time: " << std::put_time(std::localtime(&e.second), "%Y-%m-%d %H:%M:%S") << ENDL;
|
||||
ss << std::left << std::setw(15) << string_tools::get_ip_string_from_int32(e.first) << " " << std::put_time(std::localtime(&e.second), "%Y-%m-%d %H:%M:%S") << ENDL;
|
||||
}
|
||||
LOG_PRINT_L0(ss.str());
|
||||
return true;
|
||||
|
|
@ -901,6 +902,13 @@ private:
|
|||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool reload_p2p_manual_config(const std::vector<std::string>& args)
|
||||
{
|
||||
m_srv.reload_p2p_manual_config(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool print_pool(const std::vector<std::string>& args)
|
||||
{
|
||||
LOG_PRINT_L0("Pool state: " << ENDL << m_srv.get_payload_object().get_core().print_pool(false));
|
||||
|
|
|
|||
|
|
@ -121,10 +121,12 @@ namespace nodetool
|
|||
bool log_connections();
|
||||
virtual uint64_t get_connections_count();
|
||||
size_t get_outgoing_connections_count();
|
||||
size_t get_incoming_connections_count();
|
||||
peerlist_manager& get_peerlist_manager(){return m_peerlist;}
|
||||
bool handle_maintainers_entry(const maintainers_entry& me);
|
||||
bool get_maintainers_info(maintainers_info_external& me);
|
||||
void get_ip_block_list(std::map<uint32_t, time_t>& blocklist);
|
||||
bool reload_p2p_manual_config(bool silent = true);
|
||||
typedef COMMAND_REQUEST_STAT_INFO_T<typename t_payload_net_handler::stat_info> COMMAND_REQUEST_STAT_INFO;
|
||||
private:
|
||||
|
||||
|
|
@ -184,9 +186,10 @@ namespace nodetool
|
|||
virtual bool add_ip_fail(uint32_t address);
|
||||
virtual bool is_stop_signal_sent();
|
||||
//----------------- i_connection_filter --------------------------------------------------------
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress);
|
||||
virtual bool is_remote_ip_allowed(uint32_t adress, bool is_incoming);
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||
bool parse_peerlist(const std::vector<std::string>& perrs_str, std::list<nodetool::net_address>& peers);
|
||||
bool handle_command_line(const boost::program_options::variables_map& vm);
|
||||
bool idle_worker();
|
||||
bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const net_utils::connection_context_base& context);
|
||||
|
|
@ -221,7 +224,7 @@ namespace nodetool
|
|||
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);
|
||||
bool is_ip_in_blacklist(uint32_t adress, bool ignore_auto_blocked_list = false);
|
||||
|
||||
|
||||
//debug functions
|
||||
|
|
@ -298,9 +301,16 @@ namespace nodetool
|
|||
critical_section m_blocked_ips_lock;
|
||||
std::map<uint32_t, time_t> m_blocked_ips;
|
||||
|
||||
//critical_section m_permanently_blocked_ips_lock;
|
||||
std::set<uint32_t> m_permanently_blocked_ips;
|
||||
|
||||
|
||||
critical_section m_ip_fails_score_lock;
|
||||
std::map<uint32_t, uint64_t> m_ip_fails_score;
|
||||
|
||||
critical_section m_p2p_manual_config_lock;
|
||||
p2p_config_data m_p2p_manual_config;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace nodetool
|
|||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port ("hide-my-port", "Do not announce yourself as peerlist candidate");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_offline_mode ( "offline-mode", "Don't connect to any node and reject any connections");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs ( "disable-debug-p2p-requests", "Disable p2p debug requests");
|
||||
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", 1);
|
||||
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: 1", 1);
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_server_threads ( "p2p-server-threads", "Specify number of p2p server threads. Default: 10", P2P_SERVER_DEFAULT_THREADS_NUM);
|
||||
}
|
||||
|
||||
|
|
@ -106,15 +106,22 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr)
|
||||
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr, bool is_incoming)
|
||||
{
|
||||
if (m_offline_mode)
|
||||
return false;
|
||||
|
||||
if (!m_ip_auto_blocking_enabled)
|
||||
return true;
|
||||
|
||||
return !is_ip_in_blacklist(addr);
|
||||
if (is_incoming)
|
||||
{
|
||||
if (m_p2p_manual_config.incoming_connections_limit && *m_p2p_manual_config.incoming_connections_limit >= get_incoming_connections_count())
|
||||
return false;
|
||||
|
||||
if (m_use_only_priority_peers)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ignore_auto_blocked_list = !m_ip_auto_blocking_enabled;
|
||||
return !is_ip_in_blacklist(addr, ignore_auto_blocked_list);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -129,9 +136,18 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr)
|
||||
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr, bool ignore_auto_blocked_list /* = false */)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
|
||||
//first check permanently blocked ip
|
||||
if (m_permanently_blocked_ips.find(addr) != m_permanently_blocked_ips.end())
|
||||
return true;
|
||||
|
||||
if (ignore_auto_blocked_list)
|
||||
return false;
|
||||
|
||||
//check temporary blocked
|
||||
auto it = m_blocked_ips.find(addr);
|
||||
if (it == m_blocked_ips.end())
|
||||
return false;
|
||||
|
|
@ -147,6 +163,77 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::reload_p2p_manual_config(bool silent)
|
||||
{
|
||||
std::set<uint32_t> new_block_list;
|
||||
std::list<net_address> new_priority_peers;
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_p2p_manual_config_lock);
|
||||
p2p_config_data config = AUTO_VAL_INIT(config);
|
||||
std::string p2p_config_file_path = m_config_folder + "/" + P2P_MANUAL_CONFIG_FILENAME;
|
||||
bool r = epee::serialization::load_t_from_json_file(config, p2p_config_file_path);
|
||||
if (!r)
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
LOG_PRINT_L0("P2P network config file is missing or not loaded");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//loaded json, let's try to load blacklist
|
||||
for (const std::string& ip_str_entry : config.ip_black_list)
|
||||
{
|
||||
uint32_t ip = 0;
|
||||
if (!string_tools::get_ip_int32_from_string(ip, ip_str_entry))
|
||||
{
|
||||
LOG_ERROR("P2P network config file loading error: failed to convert '" << ip_str_entry << "' to ip address");
|
||||
return false;
|
||||
}
|
||||
new_block_list.insert(ip);
|
||||
}
|
||||
|
||||
if (config.priority_peers_list.size())
|
||||
{
|
||||
bool r = parse_peerlist(config.priority_peers_list, new_priority_peers);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse priority peers");
|
||||
}
|
||||
|
||||
m_p2p_manual_config = config;
|
||||
|
||||
|
||||
//override some of the settings
|
||||
if (m_p2p_manual_config.use_only_priority_peers)
|
||||
{
|
||||
m_use_only_priority_peers = *m_p2p_manual_config.use_only_priority_peers;
|
||||
}
|
||||
|
||||
m_priority_peers = new_priority_peers;
|
||||
|
||||
|
||||
if (m_p2p_manual_config.incoming_connections_limit && *m_p2p_manual_config.incoming_connections_limit == 0)
|
||||
{
|
||||
m_hide_my_port = true;
|
||||
}
|
||||
|
||||
if (m_p2p_manual_config.outgoing_connections_limit && *m_p2p_manual_config.outgoing_connections_limit == 0)
|
||||
{
|
||||
//TODO: consider if need to do this
|
||||
//m_offline_mode = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TODO: this command when passed to running daemon via command line option might be multi-thread-unsafe, subject for refactoring
|
||||
//CRITICAL_REGION_LOCAL(m_permanently_blocked_ips_lock);
|
||||
m_permanently_blocked_ips.clear();
|
||||
m_permanently_blocked_ips = new_block_list;
|
||||
|
||||
LOG_PRINT_L0("P2P network manual config file loaded(some of the p2p cpommand line options might be overridden by '" << P2P_MANUAL_CONFIG_FILENAME << "').");
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::block_ip(uint32_t addr)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
|
|
@ -188,6 +275,19 @@ namespace nodetool
|
|||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::parse_peerlist(const std::vector<std::string>& perrs_str, std::list<net_address>& peers)
|
||||
{
|
||||
for (const std::string& pr_str : perrs_str)
|
||||
{
|
||||
nodetool::net_address na = AUTO_VAL_INIT(na);
|
||||
bool r = parse_peer_from_string(na, pr_str);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
|
||||
peers.push_back(na);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::handle_command_line(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
m_bind_ip = command_line::get_arg(vm, arg_p2p_bind_ip);
|
||||
|
|
@ -236,13 +336,8 @@ namespace nodetool
|
|||
if (command_line::has_arg(vm, arg_p2p_add_priority_node))
|
||||
{
|
||||
std::vector<std::string> perrs = command_line::get_arg(vm, arg_p2p_add_priority_node);
|
||||
for(const std::string& pr_str: perrs)
|
||||
{
|
||||
nodetool::net_address na = AUTO_VAL_INIT(na);
|
||||
bool r = parse_peer_from_string(na, pr_str);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
|
||||
m_priority_peers.push_back(na);
|
||||
}
|
||||
bool r = parse_peerlist(perrs, m_priority_peers);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse priority peers");
|
||||
}
|
||||
if(command_line::has_arg(vm, arg_p2p_use_only_priority_nodes))
|
||||
m_use_only_priority_peers = true;
|
||||
|
|
@ -383,6 +478,10 @@ namespace nodetool
|
|||
LOG_PRINT_GREEN("Net service binded on " << m_bind_ip << ":" << m_listenning_port, LOG_LEVEL_0);
|
||||
if(m_external_port)
|
||||
LOG_PRINT_L0("External port defined as " << m_external_port);
|
||||
|
||||
|
||||
reload_p2p_manual_config(true);
|
||||
|
||||
return res;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
@ -842,7 +941,7 @@ namespace nodetool
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!is_remote_ip_allowed(pe.adr.ip))
|
||||
if (!is_remote_ip_allowed(pe.adr.ip, false))
|
||||
{
|
||||
++peer_index;
|
||||
continue;
|
||||
|
|
@ -912,10 +1011,22 @@ namespace nodetool
|
|||
|
||||
size_t expected_white_connections = (m_config.m_net_config.connections_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
|
||||
|
||||
size_t conn_count = get_outgoing_connections_count();
|
||||
if(conn_count < m_config.m_net_config.connections_count)
|
||||
size_t out_conn_count = get_outgoing_connections_count();
|
||||
bool need_more_connections = false;
|
||||
if (m_p2p_manual_config.outgoing_connections_limit)
|
||||
{
|
||||
if(conn_count < expected_white_connections)
|
||||
// m_p2p_manual_config always override default settings from m_config.m_net_config
|
||||
need_more_connections = out_conn_count < *m_p2p_manual_config.outgoing_connections_limit;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use default policy
|
||||
need_more_connections = out_conn_count < m_config.m_net_config.connections_count;
|
||||
}
|
||||
|
||||
if(need_more_connections)
|
||||
{
|
||||
if(out_conn_count < expected_white_connections)
|
||||
{
|
||||
//start from white list
|
||||
if(!make_expected_connections_count(true, expected_white_connections))
|
||||
|
|
@ -966,6 +1077,20 @@ namespace nodetool
|
|||
return true;
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
size_t node_server<t_payload_net_handler>::get_incoming_connections_count()
|
||||
{
|
||||
size_t count = 0;
|
||||
m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
|
||||
{
|
||||
if (cntxt.m_is_income)
|
||||
++count;
|
||||
return true;
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -289,6 +289,29 @@ namespace nodetool
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct p2p_config_data
|
||||
{
|
||||
std::optional<uint64_t> incoming_connections_limit;
|
||||
std::optional<uint64_t> outgoing_connections_limit;
|
||||
std::vector<std::string> ip_black_list;
|
||||
std::optional<bool> use_only_priority_peers = false; //allow to make outgoing connections only to the peers listed in ip_priority_list
|
||||
std::vector<std::string> priority_peers_list;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(incoming_connections_limit)
|
||||
KV_SERIALIZE(outgoing_connections_limit)
|
||||
KV_SERIALIZE(ip_black_list)
|
||||
KV_SERIALIZE(use_only_priority_peers)
|
||||
KV_SERIALIZE(priority_peers_list)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef ALLOW_DEBUG_COMMANDS
|
||||
//These commands are considered as insecure, and made in debug purposes for a limited lifetime.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
|
||||
#define SANITY_CHECK_MAX_RESERVATION_RAM 10000000
|
||||
|
||||
|
||||
//#include "serialization.h"
|
||||
template <template <bool> class Archive, class T>
|
||||
bool do_serialize(Archive<false> &ar, std::vector<T> &v);
|
||||
|
|
@ -49,7 +53,13 @@ bool do_serialize(Archive<false> &ar, std::vector<T> &v)
|
|||
return false;
|
||||
}
|
||||
|
||||
v.reserve(cnt);
|
||||
if (sizeof(T) * cnt < SANITY_CHECK_MAX_RESERVATION_RAM)
|
||||
{
|
||||
v.reserve(cnt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
if (i > 0)
|
||||
ar.delimit_array();
|
||||
|
|
|
|||
|
|
@ -306,7 +306,10 @@ simple_wallet::simple_wallet()
|
|||
m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, ph::_1), "payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N>");
|
||||
m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this,ph::_1), "Show blockchain height");
|
||||
m_cmd_binder.set_handler("wallet_bc_height", boost::bind(&simple_wallet::show_wallet_bcheight, this,ph::_1), "Show blockchain height");
|
||||
|
||||
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this,ph::_1), "transfer <mixin_count> [asset_id_1:]<addr_1> <amount_1> [ [asset_id_2:]<addr_2> <amount_2> ... [asset_id_N:]<addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available), <payment_id> is an optional HEX-encoded string");
|
||||
m_cmd_binder.set_handler("transfer_so", boost::bind(&simple_wallet::transfer_so, this, ph::_1), "transfer_so <out_idx,out_idx,...> <fee> <mixin_count> [asset_id_1:]<addr_1> <amount_1> [ [asset_id_2:]<addr_2> <amount_2> ... [asset_id_N:]<addr_N> <amount_N>] [payment_id] - Transfer funds spending only specified outputs (use list_outputs command to get outputs' indecies)");
|
||||
|
||||
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this,ph::_1), "set_log <level> - Change current log detalisation level, <level> is a number 0-4");
|
||||
m_cmd_binder.set_handler("enable_console_logger", boost::bind(&simple_wallet::enable_console_logger, this,ph::_1), "Enables console logging");
|
||||
m_cmd_binder.set_handler("resync", boost::bind(&simple_wallet::resync_wallet, this,ph::_1), "Causes wallet to reset all transfers and re-synchronize wallet");
|
||||
|
|
@ -1602,7 +1605,7 @@ bool preprocess_asset_id(std::string& address_arg, crypto::public_key& asset_id)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||
bool simple_wallet::transfer_impl(const std::vector<std::string> &args_, uint64_t fee)
|
||||
{
|
||||
CONFIRM_WITH_PASSWORD();
|
||||
SIMPLE_WALLET_BEGIN_TRY_ENTRY();
|
||||
|
|
@ -1734,7 +1737,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
}
|
||||
|
||||
currency::transaction tx;
|
||||
m_wallet->transfer(dsts, fake_outs_count, 0, m_wallet->get_core_runtime_config().tx_default_fee, extra, attachments, tx);
|
||||
m_wallet->transfer(dsts, fake_outs_count, 0, fee, extra, attachments, tx);
|
||||
|
||||
if (!m_wallet->is_watch_only())
|
||||
{
|
||||
|
|
@ -1752,6 +1755,76 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer(const std::vector<std::string> &args)
|
||||
{
|
||||
return transfer_impl(args, m_wallet->get_core_runtime_config().tx_default_fee);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::transfer_so(const std::vector<std::string> &args)
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
// 1st arg: outs
|
||||
if (args.size() <= 0)
|
||||
{
|
||||
fail_msg_writer() << "invalid agruments, can't parse outputs index array, 'out_idx,out_idx,...' format is expected";
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint64_t> outs_idxs;
|
||||
std::string outs_str = args[0];
|
||||
while (!outs_str.empty())
|
||||
{
|
||||
size_t comma_pos = outs_str.find(',');
|
||||
if (comma_pos != 0)
|
||||
{
|
||||
std::string out_idx_str = outs_str.substr(0, comma_pos);
|
||||
int64_t out_idx = -1;
|
||||
r = epee::string_tools::string_to_num_fast(out_idx_str, out_idx);
|
||||
if (!r || out_idx < 0)
|
||||
{
|
||||
fail_msg_writer() << "invalid output index given: " << out_idx_str;
|
||||
return true;
|
||||
}
|
||||
outs_idxs.push_back(out_idx);
|
||||
if (comma_pos == std::string::npos)
|
||||
break;
|
||||
}
|
||||
outs_str.erase(0, comma_pos + 1);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
for (auto i : outs_idxs)
|
||||
ss << i << " ";
|
||||
success_msg_writer() << "outputs' indicies allowed to spent: " << (outs_idxs.empty() ? std::string("all") : ss.str());
|
||||
|
||||
// 2nd arg: fee
|
||||
if (args.size() <= 1)
|
||||
{
|
||||
fail_msg_writer() << "invalid agruments: can't parse fee";
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t fee = 0;
|
||||
r = currency::parse_amount(args[1], fee);
|
||||
if (!r || fee < TX_MINIMUM_FEE)
|
||||
{
|
||||
fail_msg_writer() << "invalid agruments: given fee is invalid or too small: " << args[1] << ", minimum fee: " << print_money_brief(TX_MINIMUM_FEE);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> args_copy = args;
|
||||
args_copy.erase(args_copy.begin(), args_copy.begin() + 2); // remove first two args
|
||||
|
||||
m_wallet->set_tids_to_be_only_used_in_the_next_transfer(outs_idxs);
|
||||
auto slh = epee::misc_utils::create_scope_leave_handler([&](){
|
||||
m_wallet->set_tids_to_be_only_used_in_the_next_transfer(std::vector<uint64_t>()); // reset
|
||||
});
|
||||
transfer_impl(args_copy, fee);
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::run()
|
||||
{
|
||||
std::string addr_start = m_wallet->get_account().get_public_address_str().substr(0, 6);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,9 @@ namespace currency
|
|||
bool print_utxo_distribution(const std::vector<std::string> &args);
|
||||
bool show_blockchain_height(const std::vector<std::string> &args);
|
||||
bool show_wallet_bcheight(const std::vector<std::string> &args);
|
||||
bool transfer_impl(const std::vector<std::string> &args, uint64_t fee);
|
||||
bool transfer(const std::vector<std::string> &args);
|
||||
bool transfer_so(const std::vector<std::string> &args);
|
||||
bool resync_wallet(const std::vector<std::string> &args);
|
||||
bool print_address(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
bool show_seed(const std::vector<std::string> &args);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "7"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 418
|
||||
#define PROJECT_VERSION_BUILD_NO 424
|
||||
#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 "]"
|
||||
|
|
|
|||
|
|
@ -343,25 +343,11 @@ bool out_is_multisig(const currency::tx_out_v& out_t)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool out_is_to_htlc(const currency::tx_out_v& out_t)
|
||||
{
|
||||
if (out_t.type() == typeid(currency::tx_out_bare))
|
||||
{
|
||||
return boost::get<currency::tx_out_bare>(out_t).target.type() == typeid(currency::txout_htlc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool out_is_zc(const currency::tx_out_v& out_t)
|
||||
{
|
||||
return out_t.type() == typeid(currency::tx_out_zarcanum);
|
||||
}
|
||||
|
||||
const currency::txout_htlc& out_get_htlc(const currency::tx_out_v& out_t)
|
||||
{
|
||||
return boost::get<currency::txout_htlc>(boost::get<currency::tx_out_bare>(out_t).target);
|
||||
}
|
||||
|
||||
const crypto::public_key& wallet2::out_get_pub_key(const currency::tx_out_v& out_t, std::list<currency::htlc_info>& htlc_info_list)
|
||||
{
|
||||
if (out_t.type() == typeid(tx_out_bare))
|
||||
|
|
@ -635,32 +621,7 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
}
|
||||
VARIANT_CASE_CONST(currency::txin_htlc, in_htlc)
|
||||
{
|
||||
if (in_htlc.key_offsets.size() != 1)
|
||||
{
|
||||
LOG_ERROR("in_htlc.key_offsets.size() != 1, skip inout");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_htlc.key_offsets[0].type() != typeid(uint64_t))
|
||||
{
|
||||
LOG_ERROR("HTLC with ref_by_id is not supported by wallet yet");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto it = m_active_htlcs.find(std::make_pair(in_htlc.amount, boost::get<uint64_t>(in_htlc.key_offsets[0])));
|
||||
if (it != m_active_htlcs.end())
|
||||
{
|
||||
transfer_details& td = m_transfers.at(it->second);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout.size() > td.m_internal_output_index, "Internal error: wrong td.m_internal_output_index: " << td.m_internal_output_index);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() == typeid(tx_out_bare), "Internal error: wrong output type: " << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type().name());
|
||||
const boost::typeindex::type_info& ti = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]).target.type();
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(ti == typeid(txout_htlc), "Internal error: wrong type of output's target: " << ti.name());
|
||||
//input spend active htlc
|
||||
m_transfers.at(it->second).m_spent_height = height;
|
||||
transfer_details_extra_option_htlc_info& tdeohi = get_or_add_field_to_variant_vector<transfer_details_extra_option_htlc_info>(td.varian_options);
|
||||
tdeohi.origin = in_htlc.hltc_origin;
|
||||
tdeohi.redeem_tx_id = ptc.tx_hash();
|
||||
}
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(false, "txin_htlc is not supported");
|
||||
}
|
||||
VARIANT_SWITCH_END();
|
||||
ptc.i++;
|
||||
|
|
@ -725,10 +686,9 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
const currency::tx_out_v& out_v = tx.vout[o];
|
||||
bool out_type_zc = out_is_zc(out_v);
|
||||
bool out_type_to_key = out_is_to_key(out_v);
|
||||
bool out_type_htlc = out_is_to_htlc(out_v);
|
||||
bool out_type_multisig = out_is_multisig(out_v);
|
||||
|
||||
if (out_type_zc || out_type_to_key || out_type_htlc)
|
||||
if (out_type_zc || out_type_to_key)
|
||||
{
|
||||
crypto::public_key out_key = out_get_pub_key(out_v, htlc_info_list); // htlc_info_list contains information about which one, redeem or refund key is ours for an htlc output
|
||||
|
||||
|
|
@ -860,50 +820,8 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
}
|
||||
|
||||
size_t transfer_index = new_index;
|
||||
if (out_type_htlc)
|
||||
{
|
||||
const currency::txout_htlc& hltc = out_get_htlc(out_v);
|
||||
//mark this as spent
|
||||
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_SPENT|WALLET_TRANSFER_DETAIL_CONCISE_MODE_PRESERVE;
|
||||
//create entry for htlc input
|
||||
htlc_expiration_trigger het = AUTO_VAL_INIT(het);
|
||||
het.is_wallet_owns_redeem = (out_key == hltc.pkey_redeem) ? true : false;
|
||||
het.transfer_index = transfer_index;
|
||||
uint64_t expired_if_more_then = td.m_ptx_wallet_info->m_block_height + hltc.expiration;
|
||||
m_htlcs.insert(std::make_pair(expired_if_more_then, het));
|
||||
|
||||
if (het.is_wallet_owns_redeem)
|
||||
{
|
||||
td.m_flags |= WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM;
|
||||
}
|
||||
|
||||
//active htlc
|
||||
auto amount_gindex_pair = std::make_pair(td.m_amount, td.m_global_output_index);
|
||||
m_active_htlcs[amount_gindex_pair] = transfer_index;
|
||||
m_active_htlcs_txid[ptc.tx_hash()] = transfer_index;
|
||||
//add payer to extra options
|
||||
currency::tx_payer payer = AUTO_VAL_INIT(payer);
|
||||
if (het.is_wallet_owns_redeem)
|
||||
{
|
||||
if (currency::get_type_in_variant_container(tx.extra, payer))
|
||||
{
|
||||
crypto::chacha_crypt(payer.acc_addr, derivation);
|
||||
td.varian_options.push_back(payer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//since this is refund-mode htlc out, then sender is this wallet itself
|
||||
payer.acc_addr = m_account.get_public_address();
|
||||
td.varian_options.push_back(payer);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ptc.total_balance_change[td.get_asset_id()] += td.amount();
|
||||
add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id());
|
||||
}
|
||||
ptc.total_balance_change[td.get_asset_id()] += td.amount();
|
||||
add_transfer_to_transfers_cache(td.m_amount, transfer_index, td.get_asset_id());
|
||||
|
||||
if (td.m_key_image != currency::null_ki)
|
||||
m_key_images[td.m_key_image] = transfer_index;
|
||||
|
|
@ -931,10 +849,6 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
WLT_LOG_L0("Received asset " << print16(td.get_asset_id()) << ", transfer #" << transfer_index << ", amount: " << print_money_brief(td.amount()) << (out_type_zc ? " (hidden)" : "") << ", with tx: " << ptc.tx_hash() << ", at height " << height);
|
||||
}
|
||||
}
|
||||
else if (out_type_htlc)
|
||||
{
|
||||
WLT_LOG_L0("Detected HTLC[" << (td.m_flags & WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? "REDEEM" : "REFUND") << "], transfer #" << transfer_index << ", amount: " << print_money(td.amount()) << ", with tx: " << ptc.tx_hash() << ", at height " << height);
|
||||
}
|
||||
}
|
||||
else if (out_type_multisig)
|
||||
{
|
||||
|
|
@ -6277,108 +6191,6 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details&
|
|||
print_tx_sent_message(tx, "from multisig", true, fee);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction& tx, const crypto::hash& htlc_hash, std::string& origin)
|
||||
{
|
||||
construct_tx_param ctp = get_default_construct_tx_param();
|
||||
ctp.fee = TX_DEFAULT_FEE;
|
||||
ctp.dsts.resize(1);
|
||||
ctp.dsts.back().addr.push_back(addr);
|
||||
ctp.dsts.back().amount = amount;
|
||||
destination_option_htlc_out& htlc_option = ctp.dsts.back().htlc_options;
|
||||
htlc_option.expiration = lock_blocks_count; //about 12 hours
|
||||
htlc_option.htlc_hash = htlc_hash;
|
||||
|
||||
currency::create_and_add_tx_payer_to_container_from_address(ctp.extra,
|
||||
get_account().get_keys().account_address, get_top_block_height(), get_core_runtime_config());
|
||||
|
||||
finalized_tx ft = AUTO_VAL_INIT(ft);
|
||||
this->transfer(ctp, ft, true, nullptr);
|
||||
origin = ft.htlc_origin;
|
||||
tx = ft.tx;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::get_list_of_active_htlc(std::list<wallet_public::htlc_entry_info>& htlcs, bool only_redeem_txs)
|
||||
{
|
||||
for (auto htlc_entry : m_active_htlcs_txid)
|
||||
{
|
||||
//auto it = m_transfers.find(htlc_entry.second);
|
||||
//if (it == m_transfers.end())
|
||||
// continue;
|
||||
//const transfer_details& td = it->second;
|
||||
const transfer_details& td = m_transfers.at(htlc_entry.second);
|
||||
if (only_redeem_txs && !(td.m_flags & WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
wallet_public::htlc_entry_info entry = AUTO_VAL_INIT(entry);
|
||||
entry.tx_id = htlc_entry.first;
|
||||
if (td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type() != typeid(tx_out_bare))
|
||||
{
|
||||
//@#@
|
||||
LOG_ERROR("Unexpected output type in get_list_of_active_htlc:" << td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].type().name());
|
||||
continue;
|
||||
}
|
||||
const tx_out_bare out_b = boost::get<tx_out_bare>(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index]);
|
||||
entry.amount = out_b.amount;
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(out_b.target.type() == typeid(txout_htlc),
|
||||
"[get_list_of_active_htlc]Internal error: unexpected type of out");
|
||||
const txout_htlc& htlc = boost::get<txout_htlc>(out_b.target);
|
||||
entry.sha256_hash = htlc.htlc_hash;
|
||||
|
||||
currency::tx_payer payer = AUTO_VAL_INIT(payer);
|
||||
if (currency::get_type_in_variant_container(td.varian_options, payer))
|
||||
entry.counterparty_address = payer.acc_addr;
|
||||
|
||||
entry.is_redeem = td.m_flags & WALLET_TRANSFER_DETAIL_FLAG_HTLC_REDEEM ? true : false;
|
||||
htlcs.push_back(entry);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin)
|
||||
{
|
||||
currency::transaction result_tx = AUTO_VAL_INIT(result_tx);
|
||||
return redeem_htlc(htlc_tx_id, origin, result_tx);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin, currency::transaction& result_tx)
|
||||
{
|
||||
|
||||
construct_tx_param ctp = get_default_construct_tx_param();
|
||||
ctp.fee = TX_DEFAULT_FEE;
|
||||
ctp.htlc_tx_id = htlc_tx_id;
|
||||
ctp.htlc_origin = origin;
|
||||
ctp.dsts.resize(1);
|
||||
ctp.dsts.back().addr.push_back(m_account.get_keys().account_address);
|
||||
|
||||
auto it = m_active_htlcs_txid.find(htlc_tx_id);
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(it != m_active_htlcs_txid.end(),
|
||||
"htlc not found with tx_id = " << htlc_tx_id, API_RETURN_CODE_NOT_FOUND);
|
||||
|
||||
ctp.dsts.back().amount = m_transfers.at(it->second).amount() - ctp.fee;
|
||||
this->transfer(ctp, result_tx, true, nullptr);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id)
|
||||
{
|
||||
auto it = m_active_htlcs_txid.find(htlc_tx_id);
|
||||
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(it != m_active_htlcs_txid.end(),
|
||||
"htlc not found with tx_id = " << htlc_tx_id, API_RETURN_CODE_NOT_FOUND);
|
||||
|
||||
transfer_details_extra_option_htlc_info htlc_options = AUTO_VAL_INIT(htlc_options);
|
||||
if (!currency::get_type_in_variant_container(m_transfers.at(it->second).varian_options, htlc_options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (htlc_options.origin.size())
|
||||
{
|
||||
origin = htlc_options.origin;
|
||||
redeem_tx_id = htlc_options.redeem_tx_id;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, wallet_public::ionic_swap_proposal& proposal)
|
||||
{
|
||||
std::vector<uint64_t> selected_transfers_for_template;
|
||||
|
|
@ -6957,8 +6769,6 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, bool use_all_decoys
|
|||
VARIANT_SWITCH_BEGIN(o.target);
|
||||
VARIANT_CASE_CONST(txout_to_key, o)
|
||||
real_oe.stealth_address = o.key;
|
||||
VARIANT_CASE_CONST(txout_htlc, htlc)
|
||||
real_oe.stealth_address = htlc.pkey_refund;
|
||||
VARIANT_CASE_OTHER()
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(false,
|
||||
|
|
@ -7606,15 +7416,6 @@ bool wallet2::is_transfer_able_to_go(const transfer_details& td, uint64_t fake_o
|
|||
return false;
|
||||
}
|
||||
|
||||
VARIANT_SWITCH_BEGIN(out_v);
|
||||
VARIANT_CASE_CONST(tx_out_bare, o);
|
||||
if (o.target.type() == typeid(txout_htlc))
|
||||
{
|
||||
if (fake_outputs_count != 0)
|
||||
return false;
|
||||
}
|
||||
VARIANT_SWITCH_END();
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -7981,21 +7782,6 @@ bool wallet2::prepare_transaction(construct_tx_param& ctp, currency::finalize_tx
|
|||
}
|
||||
catch (const error::not_enough_outs_to_mix&) { return false; } // if there's not enough decoys, return false to indicate minor non-fatal error
|
||||
}
|
||||
else if (ctp.htlc_tx_id != currency::null_hash)
|
||||
{
|
||||
//htlc
|
||||
//@#@ need to do refactoring over this part to support hidden amounts and asset_id
|
||||
prepare_tx_sources_htlc(ctp.htlc_tx_id, ctp.htlc_origin, ftp.sources, needed_money_map[currency::native_coin_asset_id].found_amount);
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(ctp.dsts.size() == 1,
|
||||
"htlc: unexpected ctp.dsts.size() =" << ctp.dsts.size(), API_RETURN_CODE_INTERNAL_ERROR);
|
||||
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(needed_money_map[currency::native_coin_asset_id].found_amount > ctp.fee,
|
||||
"htlc: found money less then fee", API_RETURN_CODE_INTERNAL_ERROR);
|
||||
|
||||
//fill amount
|
||||
ctp.dsts.begin()->amount = needed_money_map[currency::native_coin_asset_id].found_amount - ctp.fee;
|
||||
|
||||
}
|
||||
else if (ctp.multisig_id != currency::null_hash)
|
||||
{
|
||||
//multisig
|
||||
|
|
@ -8448,8 +8234,6 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
|
|||
VARIANT_SWITCH_BEGIN(o.target);
|
||||
VARIANT_CASE_CONST(txout_to_key, o)
|
||||
interted_it = src.outputs.emplace(it_to_insert, out_reference, o.key);
|
||||
VARIANT_CASE_CONST(txout_htlc, htlc)
|
||||
interted_it = src.outputs.emplace(it_to_insert, out_reference, htlc.pkey_refund);
|
||||
VARIANT_CASE_OTHER()
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WITH_CODE(false,
|
||||
|
|
|
|||
|
|
@ -586,6 +586,13 @@ namespace tools
|
|||
bool truncate_transfers_and_history(const std::list<size_t>& items_to_remove);
|
||||
bool truncate_wallet();
|
||||
|
||||
void set_tids_to_be_only_used_in_the_next_transfer(const std::vector<uint64_t>& tids)
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(std::all_of(tids.cbegin(), tids.cend(), [&](size_t i){ return i < m_transfers.size(); }), "some transfers IDs are out of range");
|
||||
m_found_free_amounts.clear();
|
||||
add_transfers_to_transfers_cache(tids);
|
||||
}
|
||||
|
||||
// PoS mining
|
||||
void do_pos_mining_prepare_entry(mining_context& cxt, const transfer_details& td);
|
||||
bool do_pos_mining_iteration(mining_context& cxt, uint64_t ts);
|
||||
|
|
@ -730,17 +737,6 @@ namespace tools
|
|||
|
||||
void set_connectivity_options(unsigned int timeout);
|
||||
|
||||
/*
|
||||
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
|
||||
we use deterministic origin, if given some particular htlc_hash, then we use this hash, and this means that
|
||||
opener-hash will be given by other side
|
||||
*/
|
||||
void create_htlc_proposal(uint64_t amount, const currency::account_public_address& addr, uint64_t lock_blocks_count, currency::transaction &tx, const crypto::hash& htlc_hash, std::string &origin);
|
||||
void get_list_of_active_htlc(std::list<wallet_public::htlc_entry_info>& htlcs, bool only_redeem_txs);
|
||||
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);
|
||||
|
||||
void set_votes_config_path(const std::string& path_to_config_file);
|
||||
const tools::wallet_public::wallet_vote_config& get_current_votes() { return m_votes_config; }
|
||||
|
||||
|
|
|
|||
|
|
@ -521,11 +521,11 @@ namespace tools
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!req.comment.empty())
|
||||
if (!req.comment.empty() && payment_id.empty())
|
||||
{
|
||||
currency::tx_comment comment = AUTO_VAL_INIT(comment);
|
||||
comment.comment = req.comment;
|
||||
attachments.push_back(comment);
|
||||
extra.push_back(comment);
|
||||
}
|
||||
|
||||
if (req.push_payer && !wrap)
|
||||
|
|
@ -1142,44 +1142,6 @@ namespace tools
|
|||
WALLET_RPC_CATCH_TRY_ENTRY();
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_create_htlc_proposal(const wallet_public::COMMAND_CREATE_HTLC_PROPOSAL::request& req, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
currency::transaction tx = AUTO_VAL_INIT(tx);
|
||||
w.get_wallet()->create_htlc_proposal(req.amount, req.counterparty_address, req.lock_blocks_count, tx, req.htlc_hash, res.derived_origin_secret);
|
||||
res.result_tx_blob = currency::tx_to_blob(tx);
|
||||
res.result_tx_id = get_transaction_hash(tx);
|
||||
WALLET_RPC_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_get_list_of_active_htlc(const wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::request& req, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
w.get_wallet()->get_list_of_active_htlc(res.htlcs, req.income_redeem_only);
|
||||
WALLET_RPC_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_redeem_htlc(const wallet_public::COMMAND_REDEEM_HTLC::request& req, wallet_public::COMMAND_REDEEM_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
currency::transaction tx = AUTO_VAL_INIT(tx);
|
||||
w.get_wallet()->redeem_htlc(req.tx_id, req.origin_secret, tx);
|
||||
res.result_tx_blob = currency::tx_to_blob(tx);
|
||||
res.result_tx_id = get_transaction_hash(tx);
|
||||
WALLET_RPC_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
w.get_wallet()->check_htlc_redeemed(req.htlc_tx_id, res.origin_secrete, res.redeem_tx_id);
|
||||
WALLET_RPC_CATCH_TRY_ENTRY();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
WALLET_RPC_BEGIN_TRY_ENTRY();
|
||||
|
|
|
|||
|
|
@ -144,11 +144,6 @@ namespace tools
|
|||
MAP_JON_RPC_WE("marketplace_push_offer", on_marketplace_push_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER)
|
||||
//HTLC API
|
||||
//MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL)
|
||||
//MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC)
|
||||
//MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC)
|
||||
//MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED)
|
||||
|
||||
//IONIC_SWAPS API
|
||||
MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL)
|
||||
|
|
@ -222,11 +217,6 @@ namespace tools
|
|||
bool on_marketplace_push_update_offer(const wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER::request& req, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_marketplace_cancel_offer(const wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER::request& req, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
||||
bool on_create_htlc_proposal(const wallet_public::COMMAND_CREATE_HTLC_PROPOSAL::request& req, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_get_list_of_active_htlc(const wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::request& req, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_redeem_htlc(const wallet_public::COMMAND_REDEEM_HTLC::request& req, wallet_public::COMMAND_REDEEM_HTLC::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_check_htlc_redeemed(const wallet_public::COMMAND_CHECK_HTLC_REDEEMED::request& req, wallet_public::COMMAND_CHECK_HTLC_REDEEMED::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
||||
bool on_ionic_swap_generate_proposal(const wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_ionic_swap_get_proposal_info(const wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::request& req, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_ionic_swap_accept_proposal(const wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
|
|
|||
|
|
@ -1613,7 +1613,7 @@ std::string wallets_manager::transfer(uint64_t wallet_id, const view::transfer_p
|
|||
|
||||
|
||||
//process attachments
|
||||
if (tp.comment.size())
|
||||
if (tp.comment.size() && payment_id.empty())
|
||||
{
|
||||
currency::tx_comment tc = AUTO_VAL_INIT(tc);
|
||||
tc.comment = tp.comment;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
// Copyright (c) 2014-2021 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chaingen.h"
|
||||
|
||||
// htlc clean up, WIP -- sowle
|
||||
#if 0
|
||||
|
||||
#include "escrow_wallet_tests.h"
|
||||
#include "random_helper.h"
|
||||
#include "chaingen_helpers.h"
|
||||
|
|
@ -671,3 +674,5 @@ bool atomic_test_check_hardfork_rules::c1(currency::core& c, size_t ev_index, co
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
// Copyright (c) 2014-2021 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
|
||||
|
||||
#if 0
|
||||
|
||||
#include "chaingen.h"
|
||||
#include "wallet_tests_basic.h"
|
||||
|
||||
|
|
@ -44,3 +46,5 @@ struct atomic_test_check_hardfork_rules : public atomic_base_test
|
|||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) override;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1260,8 +1260,8 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(hard_fork_1_pos_and_locked_coins);
|
||||
|
||||
// Hardfork 2 tests
|
||||
GENERATE_AND_PLAY(hard_fork_2_tx_payer_in_wallet);
|
||||
GENERATE_AND_PLAY(hard_fork_2_tx_receiver_in_wallet);
|
||||
//GENERATE_AND_PLAY(hard_fork_2_tx_payer_in_wallet);
|
||||
//GENERATE_AND_PLAY(hard_fork_2_tx_receiver_in_wallet);
|
||||
GENERATE_AND_PLAY(hard_fork_2_tx_extra_alias_entry_in_wallet);
|
||||
GENERATE_AND_PLAY_HF(hard_fork_2_auditable_addresses_basics, "2-*");
|
||||
GENERATE_AND_PLAY(hard_fork_2_no_new_structures_before_hf);
|
||||
|
|
@ -1282,10 +1282,10 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY_HF(hard_fork_5_tx_version, "5-*");
|
||||
|
||||
// atomics
|
||||
GENERATE_AND_PLAY(atomic_simple_test);
|
||||
GENERATE_AND_PLAY(atomic_test_wrong_redeem_wrong_refund);
|
||||
GENERATE_AND_PLAY(atomic_test_altchain_simple);
|
||||
GENERATE_AND_PLAY(atomic_test_check_hardfork_rules);
|
||||
//GENERATE_AND_PLAY(atomic_simple_test);
|
||||
//GENERATE_AND_PLAY(atomic_test_wrong_redeem_wrong_refund);
|
||||
//GENERATE_AND_PLAY(atomic_test_altchain_simple);
|
||||
//GENERATE_AND_PLAY(atomic_test_check_hardfork_rules);
|
||||
|
||||
GENERATE_AND_PLAY_HF(isolate_auditable_and_proof, "2-*");
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ bool gen_double_spend_in_tx<txs_kept_by_block>::generate(std::vector<test_event_
|
|||
currency::transaction tx_1 = AUTO_VAL_INIT(tx_1);
|
||||
std::vector<currency::attachment_v> attachments;
|
||||
size_t tx_hardfork_id{};
|
||||
uint64_t tx_version = get_tx_version_from_events(events);
|
||||
uint64_t tx_version = this->get_tx_version_from_events(events);
|
||||
if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments, tx_1, tx_version, tx_hardfork_id, uint64_t(0)))
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -324,8 +324,8 @@ bool wallet_rpc_transfer::c1(currency::core& c, size_t ev_index, const std::vect
|
|||
|
||||
// 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");
|
||||
//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
|
||||
|
|
@ -357,8 +357,8 @@ bool wallet_rpc_transfer::c1(currency::core& c, size_t ev_index, const std::vect
|
|||
|
||||
// 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");
|
||||
//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;
|
||||
|
|
@ -633,37 +633,38 @@ bool wallet_rpc_exchange_suite::c1(currency::core& c, size_t ev_index, const std
|
|||
CHECK_RESPONSE_EQUAL(resp.pi.transfers_count == 6);
|
||||
CHECK_RESPONSE_EQUAL(resp.total_transfers == 6);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers.size() == 6);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].comment == TRANSFER_COMMENT);
|
||||
// below: tx_comment is temporary disabled, @#@#TODO -- sowle
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[0].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[0].payment_id) == carol_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[0].tx_hash) == carol_tx3);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[1].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[1].payment_id) == carol_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[1].tx_hash) == carol_tx2);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[2].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[2].payment_id) == carol_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[2].tx_hash) == carol_tx1);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[3].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[3].payment_id) == bob_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[3].tx_hash) == bob_tx2);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[4].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[4].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[4].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[4].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[4].payment_id) == bob_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[4].tx_hash) == bob_tx1);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[5].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[5].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[5].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[5].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[5].payment_id) == alice_payment_id);
|
||||
|
|
@ -680,25 +681,25 @@ bool wallet_rpc_exchange_suite::c1(currency::core& c, size_t ev_index, const std
|
|||
CHECK_RESPONSE_EQUAL(resp.pi.transfers_count == 6);
|
||||
CHECK_RESPONSE_EQUAL(resp.total_transfers == 6);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers.size() == 4);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[0].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[0].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[0].payment_id) == carol_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[0].tx_hash) == carol_tx1);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[1].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[1].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[1].payment_id) == bob_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[1].tx_hash) == bob_tx2);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[2].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[2].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[2].payment_id) == bob_payment_id);
|
||||
CHECK_RESPONSE_EQUAL(boost::lexical_cast<std::string>(resp.transfers[2].tx_hash) == bob_tx1);
|
||||
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(resp.transfers[3].comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(resp.transfers[3].is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(resp.transfers[3].payment_id) == alice_payment_id);
|
||||
|
|
@ -737,7 +738,7 @@ bool wallet_rpc_exchange_suite::c1(currency::core& c, size_t ev_index, const std
|
|||
|
||||
|
||||
CHECK_RESPONSE_EQUAL(st_resp.in.size() == 1);
|
||||
CHECK_RESPONSE_EQUAL(st_resp.in.begin()->comment == TRANSFER_COMMENT);
|
||||
//CHECK_RESPONSE_EQUAL(st_resp.in.begin()->comment == TRANSFER_COMMENT);
|
||||
CHECK_RESPONSE_EQUAL(st_resp.in.begin()->amount == TRANSFER_AMOUNT);
|
||||
CHECK_RESPONSE_EQUAL(st_resp.in.begin()->is_income == true);
|
||||
CHECK_RESPONSE_EQUAL(epee::string_tools::buff_to_hex_nodelimer(st_resp.in.begin()->payment_id) == bob_payment_id);
|
||||
|
|
|
|||
|
|
@ -3545,8 +3545,9 @@ bool wallet_sending_to_integrated_address::c1(currency::core& c, size_t ev_index
|
|||
if (wti.payment_id.empty())
|
||||
return true; // skip another outputs
|
||||
CHECK_AND_ASSERT_MES(wti.payment_id == payment_id, false, "incorrect payment id");
|
||||
CHECK_AND_ASSERT_MES(wti.remote_addresses.size() == 1, false, "remote_addressed.size() = " << wti.remote_addresses.size());
|
||||
CHECK_AND_ASSERT_MES(wti.remote_addresses[0] == alice_integrated_address, false, "incorrect remote address");
|
||||
// below: tx_payer and tx_receiver are temporary disabled, @#@#TODO -- sowle
|
||||
//CHECK_AND_ASSERT_MES(wti.remote_addresses.size() == 1, false, "remote_addressed.size() = " << wti.remote_addresses.size());
|
||||
//CHECK_AND_ASSERT_MES(wti.remote_addresses[0] == alice_integrated_address, false, "incorrect remote address");
|
||||
callback_succeded = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue