aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md44
-rw-r--r--contrib/epee/include/net/http_client.h94
-rw-r--r--contrib/epee/include/net/http_client_abstract_invoke.h101
-rw-r--r--contrib/epee/include/net/net_helper.h51
-rw-r--r--contrib/epee/include/storages/http_abstract_invoke.h34
-rw-r--r--contrib/epee/src/CMakeLists.txt10
-rw-r--r--src/common/dns_utils.cpp16
-rw-r--r--src/common/dns_utils.h7
-rw-r--r--src/common/http_connection.h17
-rw-r--r--src/common/rpc_client.h35
-rw-r--r--src/common/unordered_containers_boost_serialization.h6
-rw-r--r--src/cryptonote_core/blockchain.cpp3
-rw-r--r--src/cryptonote_core/blockchain.h1
-rw-r--r--src/cryptonote_core/cryptonote_basic_impl.cpp30
-rw-r--r--src/cryptonote_core/cryptonote_basic_impl.h14
-rw-r--r--src/cryptonote_core/cryptonote_boost_serialization.h1
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp12
-rw-r--r--src/cryptonote_core/cryptonote_format_utils.cpp33
-rw-r--r--src/cryptonote_core/miner.cpp3
-rw-r--r--src/cryptonote_core/tx_pool.cpp20
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp1
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl14
-rw-r--r--src/daemon/protocol.h1
-rw-r--r--src/daemon/rpc_command_executor.cpp1
-rw-r--r--src/p2p/connection_basic.cpp1
-rw-r--r--src/p2p/net_node.h1
-rw-r--r--src/p2p/net_node.inl4
-rw-r--r--src/p2p/net_peerlist.h10
-rw-r--r--src/p2p/network_throttle-detail.cpp1
-rw-r--r--src/p2p/network_throttle.hpp1
-rw-r--r--src/p2p/p2p_protocol_defs.h2
-rw-r--r--src/ringct/rctTypes.h2
-rw-r--r--src/rpc/core_rpc_server.cpp34
-rw-r--r--src/simplewallet/simplewallet.cpp50
-rw-r--r--src/simplewallet/simplewallet.h1
-rw-r--r--src/wallet/api/wallet.cpp142
-rw-r--r--src/wallet/api/wallet.h7
-rw-r--r--src/wallet/api/wallet_manager.cpp57
-rw-r--r--src/wallet/api/wallet_manager.h7
-rw-r--r--src/wallet/node_rpc_proxy.cpp28
-rw-r--r--src/wallet/node_rpc_proxy.h6
-rw-r--r--src/wallet/wallet2.cpp99
-rw-r--r--src/wallet/wallet2.h26
-rw-r--r--src/wallet/wallet2_api.h20
-rw-r--r--src/wallet/wallet_rpc_server.cpp2
-rw-r--r--tests/core_tests/chaingen_main.cpp2
-rw-r--r--tests/functional_tests/transactions_flow_test.cpp4
47 files changed, 599 insertions, 457 deletions
diff --git a/README.md b/README.md
index a6a57da2b..436e8398d 100644
--- a/README.md
+++ b/README.md
@@ -385,6 +385,50 @@ If you want to help out, see CONTRIBUTING for a set of guidelines.
This section contains general instructions for debugging failed installs or problems encountered with Monero. First ensure you are running the latest version built from the github repo.
+## Obtaining Stack Traces and Core Dumps on Unix Systems
+
+We generally use the tool `gdb` (GNU debugger) to provide stack trace functionality, and `ulimit` to provide core dumps in builds which crash or segfault.
+
+* To use gdb in order to obtain a stack trace for a build that has stalled:
+
+Run the build.
+
+Once it stalls, enter the following command:
+
+```
+gdb /path/to/monerod `pidof monerod`
+```
+
+Type `thread apply all bt` within gdb in order to obtain the stack trace
+
+* If however the core dumps or segfaults:
+
+Enter `ulimit -c unlimited` on the command line to enable unlimited filesizes for core dumps
+
+Run the build.
+
+When it terminates with an output along the lines of "Segmentation fault (core dumped)", there should be a core dump file in the same directory as monerod.
+
+You can now analyse this core dump with `gdb` as follows:
+
+`gdb /path/to/monerod /path/to/dumpfile`
+
+Print the stack trace with `bt`
+
+* To run monero within gdb:
+
+Type `gdb /path/to/monerod`
+
+Pass command-line options with `--args` followed by the relevant arguments
+
+Type `run` to run monerod
+
+## Analysing Memory Corruption
+
+We use the tool `valgrind` for this.
+
+Run with `valgrind /path/to/monerod`. It will be slow.
+
## LMDB
Instructions for debugging suspected blockchain corruption as per @HYC
diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h
index a54318ebb..c5aeb9251 100644
--- a/contrib/epee/include/net/http_client.h
+++ b/contrib/epee/include/net/http_client.h
@@ -263,7 +263,6 @@ using namespace std;
blocked_mode_client m_net_client;
std::string m_host_buff;
std::string m_port;
- unsigned int m_timeout;
std::string m_header_cache;
http_response_info m_response_info;
size_t m_len_in_summary;
@@ -276,23 +275,43 @@ using namespace std;
critical_section m_lock;
public:
- void set_host_name(const std::string& name)
+ explicit http_simple_client()
+ : i_target_handler()
+ , m_net_client()
+ , m_host_buff()
+ , m_port()
+ , m_header_cache()
+ , m_response_info()
+ , m_len_in_summary(0)
+ , m_len_in_remain(0)
+ , m_pcontent_encoding_handler(nullptr)
+ , m_state()
+ , m_chunked_state()
+ , m_chunked_cache()
+ , m_lock()
+ {}
+
+ bool set_server(const std::string& address)
+ {
+ http::url_content parsed{};
+ const bool r = parse_url(address, parsed);
+ CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
+ set_server(std::move(parsed.host), std::to_string(parsed.port));
+ return true;
+ }
+
+ void set_server(std::string host, std::string port)
{
CRITICAL_REGION_LOCAL(m_lock);
- m_host_buff = name;
+ disconnect();
+ m_host_buff = std::move(host);
+ m_port = std::move(port);
}
- bool connect(const std::string& host, int port, unsigned int timeout)
- {
- return connect(host, std::to_string(port), timeout);
- }
- bool connect(const std::string& host, const std::string& port, unsigned int timeout)
+
+ bool connect(std::chrono::milliseconds timeout)
{
CRITICAL_REGION_LOCAL(m_lock);
- m_host_buff = host;
- m_port = port;
- m_timeout = timeout;
-
- return m_net_client.connect(host, port, timeout, timeout);
+ return m_net_client.connect(m_host_buff, m_port, timeout);
}
//---------------------------------------------------------------------------
bool disconnect()
@@ -316,20 +335,20 @@ using namespace std;
}
//---------------------------------------------------------------------------
inline
- bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ bool invoke_get(const std::string& uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
- return invoke(uri, "GET", body, ppresponse_info, additional_params);
+ return invoke(uri, "GET", body, timeout, ppresponse_info, additional_params);
}
//---------------------------------------------------------------------------
- inline bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke(const std::string& uri, const std::string& method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
if(!is_connected())
{
MDEBUG("Reconnecting...");
- if(!connect(m_host_buff, m_port, m_timeout))
+ if(!connect(timeout))
{
MDEBUG("Failed to connect to " << m_host_buff << ":" << m_port);
return false;
@@ -347,27 +366,27 @@ using namespace std;
req_buff += "\r\n";
//--
- bool res = m_net_client.send(req_buff);
+ bool res = m_net_client.send(req_buff, timeout);
CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
if(body.size())
- res = m_net_client.send(body);
+ res = m_net_client.send(body, timeout);
CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
if(ppresponse_info)
*ppresponse_info = &m_response_info;
m_state = reciev_machine_state_header;
- return handle_reciev();
+ return handle_reciev(timeout);
}
//---------------------------------------------------------------------------
- inline bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke_post(const std::string& uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
- return invoke(uri, "POST", body, ppresponse_info, additional_params);
+ return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params);
}
private:
//---------------------------------------------------------------------------
- inline bool handle_reciev()
+ inline bool handle_reciev(std::chrono::milliseconds timeout)
{
CRITICAL_REGION_LOCAL(m_lock);
bool keep_handling = true;
@@ -377,7 +396,7 @@ using namespace std;
{
if(need_more_data)
{
- if(!m_net_client.recv(recv_buffer))
+ if(!m_net_client.recv(recv_buffer, timeout))
{
MERROR("Unexpected recv fail");
m_state = reciev_machine_state_error;
@@ -878,33 +897,6 @@ using namespace std;
return true;
}
};
-
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- //inline
- template<class t_transport>
- bool invoke_request(const std::string& url, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
- {
- http::url_content u_c;
- bool res = parse_url(url, u_c);
-
- if(!tr.is_connected() && !u_c.host.empty())
- {
- CHECK_AND_ASSERT_MES(res, false, "failed to parse url: " << url);
-
- if(!u_c.port)
- u_c.port = 80;//default for http
-
- res = tr.connect(u_c.host, static_cast<int>(u_c.port), timeout);
- CHECK_AND_ASSERT_MES(res, false, "failed to connect " << u_c.host << ":" << u_c.port);
- }
-
- return tr.invoke(u_c.uri, method, body, ppresponse_info, additional_params);
- }
-
}
}
}
diff --git a/contrib/epee/include/net/http_client_abstract_invoke.h b/contrib/epee/include/net/http_client_abstract_invoke.h
deleted file mode 100644
index 9b6ab4db8..000000000
--- a/contrib/epee/include/net/http_client_abstract_invoke.h
+++ /dev/null
@@ -1,101 +0,0 @@
-
-// Copyright (c) 2006-2013, 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
-#include "storages/serializeble_struct_helper.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
-
-namespace epee
-{
- namespace net_utils
- {
- namespace http
- {
- template<class TArg, class TResult, class TTransport>
- bool invoke_http_json_remote_command(const std::string& url, TArg& out_struct, TResult& result_struct, TTransport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
- {
- std::string req_param;
- StorageNamed::InMemStorageSpace::json::store_t_to_json(out_struct, req_param);
-
- const http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url);
- return false;
- }
-
- if(!pri->m_response_code)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
- return false;
- }
-
- if(pri->m_response_code != 200)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
- return false;
- }
-
- return StorageNamed::InMemStorageSpace::json::load_t_from_json(result_struct, pri->m_body);
- }
-
-
-
- template<class TArg, class TResult, class TTransport>
- bool invoke_http_bin_remote_command(const std::string& url, TArg& out_struct, TResult& result_struct, TTransport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
- {
- std::string req_param;
- epee::StorageNamed::save_struct_as_storage_to_buff(out_struct, req_param);
-
- const http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url);
- return false;
- }
-
- if(!pri->m_response_code)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
- return false;
- }
-
- if(pri->m_response_code != 200)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
- return false;
- }
-
- return epee::StorageNamed::load_struct_from_storage_buff(result_struct, pri->m_body);
- }
-
-
- }
- }
-}
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index 22cea122f..432169990 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -37,6 +37,7 @@
#include <ostream>
#include <string>
#include <boost/asio.hpp>
+#include <boost/asio/steady_timer.hpp>
#include <boost/preprocessor/selection/min.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
@@ -98,7 +99,7 @@ namespace net_utils
// No deadline is required until the first socket operation is started. We
// set the deadline to positive infinity so that the actor takes no action
// until a specific deadline is set.
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
// Start the persistent actor that checks for deadline expiry.
check_deadline();
@@ -111,26 +112,16 @@ namespace net_utils
shutdown();
}
- inline void set_recv_timeout(int reciev_timeout)
- {
- m_reciev_timeout = reciev_timeout;
- }
-
inline
- bool connect(const std::string& addr, int port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
+ bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0")
{
- return connect(addr, std::to_string(port), connect_timeout, reciev_timeout, bind_ip);
+ return connect(addr, std::to_string(port), timeout, bind_ip);
}
inline
- bool connect(const std::string& addr, const std::string& port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
+ bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0")
{
- m_connect_timeout = connect_timeout;
- m_reciev_timeout = reciev_timeout;
m_connected = false;
- if(!m_reciev_timeout)
- m_reciev_timeout = m_connect_timeout;
-
try
{
m_socket.close();
@@ -164,7 +155,7 @@ namespace net_utils
}
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_connect_timeout));
+ m_deadline.expires_from_now(timeout);
boost::system::error_code ec = boost::asio::error::would_block;
@@ -179,7 +170,7 @@ namespace net_utils
if (!ec && m_socket.is_open())
{
m_connected = true;
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
return true;
}else
{
@@ -231,12 +222,12 @@ namespace net_utils
inline
- bool send(const std::string& buff)
+ bool send(const std::string& buff, std::chrono::milliseconds timeout)
{
try
{
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -264,7 +255,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
}
@@ -322,7 +313,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
}
@@ -350,7 +341,7 @@ namespace net_utils
}
inline
- bool recv(std::string& buff)
+ bool recv(std::string& buff, std::chrono::milliseconds timeout)
{
try
@@ -358,7 +349,7 @@ namespace net_utils
// Set a deadline for the asynchronous operation. Since this function uses
// a composed operation (async_read_until), the deadline applies to the
// entire operation, rather than individual reads from the socket.
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -404,7 +395,7 @@ namespace net_utils
}else
{
MTRACE("READ ENDS: Success. bytes_tr: " << bytes_transfered);
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
/*if(!bytes_transfered)
@@ -432,7 +423,7 @@ namespace net_utils
}
- inline bool recv_n(std::string& buff, int64_t sz)
+ inline bool recv_n(std::string& buff, int64_t sz, std::chrono::milliseconds timeout)
{
try
@@ -440,7 +431,7 @@ namespace net_utils
// Set a deadline for the asynchronous operation. Since this function uses
// a composed operation (async_read_until), the deadline applies to the
// entire operation, rather than individual reads from the socket.
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -477,7 +468,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
if(bytes_transfered != buff.size())
@@ -539,7 +530,7 @@ namespace net_utils
// Check whether the deadline has passed. We compare the deadline against
// the current time since a new asynchronous operation may have moved the
// deadline before this actor had a chance to run.
- if (m_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now())
+ if (m_deadline.expires_at() <= std::chrono::steady_clock::now())
{
// The deadline has passed. The socket is closed so that any outstanding
// asynchronous operations are cancelled. This allows the blocked
@@ -550,7 +541,7 @@ namespace net_utils
// There is no longer an active deadline. The expiry is set to positive
// infinity so that the actor takes no action until a new deadline is set.
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
// Put the actor back to sleep.
@@ -562,11 +553,9 @@ namespace net_utils
protected:
boost::asio::io_service m_io_service;
boost::asio::ip::tcp::socket m_socket;
- int m_connect_timeout;
- int m_reciev_timeout;
bool m_initialized;
bool m_connected;
- boost::asio::deadline_timer m_deadline;
+ boost::asio::steady_timer m_deadline;
volatile uint32_t m_shutdowned;
};
diff --git a/contrib/epee/include/storages/http_abstract_invoke.h b/contrib/epee/include/storages/http_abstract_invoke.h
index 00ee8a4ad..36177c7e0 100644
--- a/contrib/epee/include/storages/http_abstract_invoke.h
+++ b/contrib/epee/include/storages/http_abstract_invoke.h
@@ -35,28 +35,28 @@ namespace epee
namespace net_utils
{
template<class t_request, class t_response, class t_transport>
- bool invoke_http_json_remote_command2(const std::string& url, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
+ bool invoke_http_json(const std::string& uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& method = "GET")
{
std::string req_param;
if(!serialization::store_t_to_json(out_struct, req_param))
return false;
const http::http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
+ if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
{
- LOG_PRINT_L1("Failed to invoke http request to " << url);
+ LOG_PRINT_L1("Failed to invoke http request to " << uri);
return false;
}
- if(!pri->m_response_code)
+ if(!pri)
{
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
+ LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
return false;
}
if(pri->m_response_code != 200)
{
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
+ LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
return false;
}
@@ -66,28 +66,28 @@ namespace epee
template<class t_request, class t_response, class t_transport>
- bool invoke_http_bin_remote_command2(const std::string& url, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
+ bool invoke_http_bin(const std::string& uri, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& method = "GET")
{
std::string req_param;
if(!serialization::store_t_to_binary(out_struct, req_param))
return false;
const http::http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
+ if(!transport.invoke(uri, method, req_param, timeout, std::addressof(pri)))
{
- LOG_PRINT_L1("Failed to invoke http request to " << url);
+ LOG_PRINT_L1("Failed to invoke http request to " << uri);
return false;
}
- if(!pri->m_response_code)
+ if(!pri)
{
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
+ LOG_PRINT_L1("Failed to invoke http request to " << uri << ", internal error (null response ptr)");
return false;
}
if(pri->m_response_code != 200)
{
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
+ LOG_PRINT_L1("Failed to invoke http request to " << uri << ", wrong response code: " << pri->m_response_code);
return false;
}
@@ -95,15 +95,15 @@ namespace epee
}
template<class t_request, class t_response, class t_transport>
- bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
+ bool invoke_http_json_rpc(const std::string& uri, std::string method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& http_method = "GET", const std::string& req_id = "0")
{
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
req_t.jsonrpc = "2.0";
req_t.id = req_id;
- req_t.method = method_name;
+ req_t.method = std::move(method_name);
req_t.params = out_struct;
epee::json_rpc::response<t_response, epee::json_rpc::error> resp_t = AUTO_VAL_INIT(resp_t);
- if(!epee::net_utils::invoke_http_json_remote_command2(url, req_t, resp_t, transport, timeout, http_method))
+ if(!epee::net_utils::invoke_http_json(uri, req_t, resp_t, transport, timeout, http_method))
{
return false;
}
@@ -117,9 +117,9 @@ namespace epee
}
template<class t_command, class t_transport>
- bool invoke_http_json_rpc(const std::string& url, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
+ bool invoke_http_json_rpc(const std::string& uri, typename t_command::request& out_struct, typename t_command::response& result_struct, t_transport& transport, std::chrono::milliseconds timeout = std::chrono::seconds(5), const std::string& http_method = "GET", const std::string& req_id = "0")
{
- return invoke_http_json_rpc(url, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
+ return invoke_http_json_rpc(uri, t_command::methodname(), out_struct, result_struct, transport, timeout, http_method, req_id);
}
}
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 8bc512893..93c9a94f7 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -27,3 +27,13 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
add_library(epee STATIC http_auth.cpp mlog.cpp)
+# Build and install libepee if we're building for GUI
+if (BUILD_GUI_DEPS)
+ if(IOS)
+ set(lib_folder lib-${ARCH})
+ else()
+ set(lib_folder lib)
+ endif()
+ install(TARGETS epee
+ ARCHIVE DESTINATION ${lib_folder})
+endif() \ No newline at end of file
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 2efdcffcd..83259bc70 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -451,22 +451,6 @@ std::string get_account_address_as_str_from_url(const std::string& url, bool& dn
return addresses[0];
}
-bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , const std::string& str_or_url
- )
-{
- if (cryptonote::get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, str_or_url))
- return true;
- bool dnssec_valid;
- std::string address_str = get_account_address_as_str_from_url(str_or_url, dnssec_valid);
- return !address_str.empty() &&
- cryptonote::get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, address_str);
-}
-
} // namespace tools::dns_utils
} // namespace tools
diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h
index 5fe1d4775..8a63a8129 100644
--- a/src/common/dns_utils.h
+++ b/src/common/dns_utils.h
@@ -164,13 +164,6 @@ std::string address_from_txt_record(const std::string& s);
std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid);
std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid);
-bool get_account_address_from_str_or_url(
- cryptonote::account_public_address& address
- , bool& has_payment_id
- , crypto::hash8& payment_id
- , bool testnet
- , const std::string& str_or_url
- );
} // namespace tools::dns_utils
diff --git a/src/common/http_connection.h b/src/common/http_connection.h
index 156474cdd..8a786361a 100644
--- a/src/common/http_connection.h
+++ b/src/common/http_connection.h
@@ -28,6 +28,7 @@
#pragma once
+#include <chrono>
#include "string_tools.h"
#include "net/http_client.h"
@@ -38,20 +39,16 @@ private:
epee::net_utils::http::http_simple_client * mp_http_client;
bool m_ok;
public:
- static unsigned int const TIMEOUT = 200000;
+ static constexpr std::chrono::seconds TIMEOUT()
+ {
+ return std::chrono::minutes(3) + std::chrono::seconds(30);
+ }
- t_http_connection(
- epee::net_utils::http::http_simple_client * p_http_client
- , uint32_t ip
- , uint16_t port
- )
+ t_http_connection(epee::net_utils::http::http_simple_client* p_http_client)
: mp_http_client(p_http_client)
, m_ok(false)
{
- // TODO fix http client so that it accepts properly typed arguments
- std::string ip_str = epee::string_tools::get_ip_string_from_int32(ip);
- std::string port_str = boost::lexical_cast<std::string>(port);
- m_ok = mp_http_client->connect(ip_str, port_str, TIMEOUT);
+ m_ok = mp_http_client->connect(TIMEOUT());
}
~t_http_connection()
diff --git a/src/common/rpc_client.h b/src/common/rpc_client.h
index 9c0036198..f5ecc8b50 100644
--- a/src/common/rpc_client.h
+++ b/src/common/rpc_client.h
@@ -34,7 +34,6 @@
#include "storages/http_abstract_invoke.h"
#include "net/http_client.h"
#include "string_tools.h"
-#include <boost/lexical_cast.hpp>
namespace tools
{
@@ -42,27 +41,16 @@ namespace tools
{
private:
epee::net_utils::http::http_simple_client m_http_client;
- uint32_t m_ip;
- uint16_t m_port;
public:
t_rpc_client(
uint32_t ip
, uint16_t port
)
: m_http_client{}
- , m_ip{ip}
- , m_port{port}
- {}
-
- std::string build_url(std::string const & relative_url) const
{
- std::string result =
- "http://"
- + epee::string_tools::get_ip_string_from_int32(m_ip)
- + ":"
- + boost::lexical_cast<std::string>(m_port)
- + relative_url;
- return result;
+ m_http_client.set_server(
+ epee::string_tools::get_ip_string_from_int32(ip), std::to_string(port)
+ );
}
template <typename T_req, typename T_res>
@@ -72,8 +60,7 @@ namespace tools
, std::string const & method_name
)
{
- std::string rpc_url = build_url("/json_rpc");
- t_http_connection connection(&m_http_client, m_ip, m_port);
+ t_http_connection connection(&m_http_client);
bool ok = connection.is_open();
if (!ok)
@@ -81,7 +68,7 @@ namespace tools
fail_msg_writer() << "Couldn't connect to daemon";
return false;
}
- ok = ok && epee::net_utils::invoke_http_json_rpc(rpc_url, method_name, req, res, m_http_client);
+ ok = ok && epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT());
if (!ok)
{
fail_msg_writer() << "Daemon request failed";
@@ -101,11 +88,10 @@ namespace tools
, std::string const & fail_msg
)
{
- std::string rpc_url = build_url("/json_rpc");
- t_http_connection connection(&m_http_client, m_ip, m_port);
+ t_http_connection connection(&m_http_client);
bool ok = connection.is_open();
- ok = ok && epee::net_utils::invoke_http_json_rpc(rpc_url, method_name, req, res, m_http_client);
+ ok = ok && epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT());
if (!ok)
{
fail_msg_writer() << "Couldn't connect to daemon";
@@ -130,11 +116,10 @@ namespace tools
, std::string const & fail_msg
)
{
- std::string rpc_url = build_url(relative_url);
- t_http_connection connection(&m_http_client, m_ip, m_port);
+ t_http_connection connection(&m_http_client);
bool ok = connection.is_open();
- ok = ok && epee::net_utils::invoke_http_json_remote_command2(rpc_url, req, res, m_http_client);
+ ok = ok && epee::net_utils::invoke_http_json(relative_url, req, res, m_http_client, t_http_connection::TIMEOUT());
if (!ok)
{
fail_msg_writer() << "Couldn't connect to daemon";
@@ -153,7 +138,7 @@ namespace tools
bool check_connection()
{
- t_http_connection connection(&m_http_client, m_ip, m_port);
+ t_http_connection connection(&m_http_client);
return connection.is_open();
}
};
diff --git a/src/common/unordered_containers_boost_serialization.h b/src/common/unordered_containers_boost_serialization.h
index 08b5d9ccf..b2d5b27a6 100644
--- a/src/common/unordered_containers_boost_serialization.h
+++ b/src/common/unordered_containers_boost_serialization.h
@@ -43,7 +43,7 @@ namespace boost
{
size_t s = x.size();
a << s;
- BOOST_FOREACH(auto& v, x)
+ for(auto& v: x)
{
a << v.first;
a << v.second;
@@ -72,7 +72,7 @@ namespace boost
{
size_t s = x.size();
a << s;
- BOOST_FOREACH(auto& v, x)
+ for(auto& v: x)
{
a << v.first;
a << v.second;
@@ -101,7 +101,7 @@ namespace boost
{
size_t s = x.size();
a << s;
- BOOST_FOREACH(auto& v, x)
+ for(auto& v: x)
{
a << v;
}
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 789687ce0..b344c5597 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -31,6 +31,7 @@
#include <algorithm>
#include <cstdio>
#include <boost/filesystem.hpp>
+#include <boost/range/adaptor/reversed.hpp>
#include "include_base_utils.h"
#include "cryptonote_basic_impl.h"
@@ -933,7 +934,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
size_t count = 0;
size_t max_i = timestamps.size()-1;
// get difficulties and timestamps from most recent blocks in alt chain
- BOOST_REVERSE_FOREACH(auto it, alt_chain)
+ for(auto it: boost::adaptors::reverse(alt_chain))
{
timestamps[max_i - count] = it->second.bl.timestamp;
cumulative_difficulties[max_i - count] = it->second.cumulative_difficulty;
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index ca665e1d4..cd452faf4 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -36,7 +36,6 @@
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
-#include <boost/foreach.hpp>
#include <atomic>
#include <unordered_map>
#include <unordered_set>
diff --git a/src/cryptonote_core/cryptonote_basic_impl.cpp b/src/cryptonote_core/cryptonote_basic_impl.cpp
index 5a8c61dd9..51c9269a5 100644
--- a/src/cryptonote_core/cryptonote_basic_impl.cpp
+++ b/src/cryptonote_core/cryptonote_basic_impl.cpp
@@ -41,6 +41,7 @@ using namespace epee;
#include "common/base58.h"
#include "crypto/hash.h"
#include "common/int-util.h"
+#include "common/dns_utils.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "cn"
@@ -291,7 +292,34 @@ namespace cryptonote {
crypto::hash8 payment_id;
return get_account_integrated_address_from_str(adr, has_payment_id, payment_id, testnet, str);
}
-
+ //--------------------------------------------------------------------------------
+ bool get_account_address_from_str_or_url(
+ cryptonote::account_public_address& address
+ , bool& has_payment_id
+ , crypto::hash8& payment_id
+ , bool testnet
+ , const std::string& str_or_url
+ )
+ {
+ if (get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, str_or_url))
+ return true;
+ bool dnssec_valid;
+ std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid);
+ return !address_str.empty() &&
+ get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, address_str);
+ }
+ //--------------------------------------------------------------------------------
+ bool get_account_address_from_str_or_url(
+ cryptonote::account_public_address& address
+ , bool testnet
+ , const std::string& str_or_url
+ )
+ {
+ bool has_payment_id;
+ crypto::hash8 payment_id;
+ return get_account_address_from_str_or_url(address, testnet, str_or_url);
+ }
+ //--------------------------------------------------------------------------------
bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) {
return cryptonote::get_transaction_hash(a) == cryptonote::get_transaction_hash(b);
}
diff --git a/src/cryptonote_core/cryptonote_basic_impl.h b/src/cryptonote_core/cryptonote_basic_impl.h
index 147bc89ba..5703a7d75 100644
--- a/src/cryptonote_core/cryptonote_basic_impl.h
+++ b/src/cryptonote_core/cryptonote_basic_impl.h
@@ -100,6 +100,20 @@ namespace cryptonote {
, const std::string& str
);
+ bool get_account_address_from_str_or_url(
+ cryptonote::account_public_address& address
+ , bool& has_payment_id
+ , crypto::hash8& payment_id
+ , bool testnet
+ , const std::string& str_or_url
+ );
+
+ bool get_account_address_from_str_or_url(
+ cryptonote::account_public_address& address
+ , bool testnet
+ , const std::string& str_or_url
+ );
+
bool is_coinbase(const transaction& tx);
bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b);
diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h
index 7423b222a..409b9798c 100644
--- a/src/cryptonote_core/cryptonote_boost_serialization.h
+++ b/src/cryptonote_core/cryptonote_boost_serialization.h
@@ -35,7 +35,6 @@
#include <boost/serialization/variant.hpp>
#include <boost/serialization/set.hpp>
#include <boost/serialization/map.hpp>
-#include <boost/foreach.hpp>
#include <boost/serialization/is_bitwise_serializable.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 22d473b35..5ddedd6fd 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -31,7 +31,6 @@
#include "include_base_utils.h"
using namespace epee;
-#include <boost/foreach.hpp>
#include <unordered_set>
#include "cryptonote_core.h"
#include "common/command_line.h"
@@ -532,6 +531,7 @@ namespace cryptonote
if (rv.outPk.size() != tx.vout.size())
{
LOG_PRINT_L1("WRONG TRANSACTION BLOB, Bad outPk size in tx " << tx_hash << ", rejected");
+ tvc.m_verifivation_failed = true;
return false;
}
for (size_t n = 0; n < tx.rct_signatures.outPk.size(); ++n)
@@ -668,7 +668,7 @@ namespace cryptonote
bool core::are_key_images_spent(const std::vector<crypto::key_image>& key_im, std::vector<bool> &spent) const
{
spent.clear();
- BOOST_FOREACH(auto& ki, key_im)
+ for(auto& ki: key_im)
{
spent.push_back(m_blockchain_storage.have_tx_keyimg_as_spent(ki));
}
@@ -681,14 +681,14 @@ namespace cryptonote
uint64_t emission_amount = 0;
uint64_t total_fee_amount = 0;
this->get_blocks(start_offset, count, blocks);
- BOOST_FOREACH(auto& b, blocks)
+ for(auto& b: blocks)
{
std::list<transaction> txs;
std::list<crypto::hash> missed_txs;
uint64_t coinbase_amount = get_outs_money_amount(b.miner_tx);
this->get_transactions(b.tx_hashes, txs, missed_txs);
uint64_t tx_fee_amount = 0;
- BOOST_FOREACH(const auto& tx, txs)
+ for(const auto& tx: txs)
{
tx_fee_amount += get_tx_fee(tx);
}
@@ -703,7 +703,7 @@ namespace cryptonote
bool core::check_tx_inputs_keyimages_diff(const transaction& tx) const
{
std::unordered_set<crypto::key_image> ki;
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
if(!ki.insert(tokey_in.k_image).second)
@@ -869,7 +869,7 @@ namespace cryptonote
block_to_blob(b, arg.b.block);
//pack transactions
- BOOST_FOREACH(auto& tx, txs)
+ for(auto& tx: txs)
arg.b.txs.push_back(t_serializable_object_to_blob(tx));
m_pprotocol->relay_block(arg, exclude_context);
diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp
index e04409d87..70ba7ee18 100644
--- a/src/cryptonote_core/cryptonote_format_utils.cpp
+++ b/src/cryptonote_core/cryptonote_format_utils.cpp
@@ -32,7 +32,6 @@
using namespace epee;
#include "cryptonote_format_utils.h"
-#include <boost/foreach.hpp>
#include "cryptonote_config.h"
#include "miner.h"
#include "crypto/crypto.h"
@@ -274,12 +273,12 @@ namespace cryptonote
}
uint64_t amount_in = 0;
uint64_t amount_out = 0;
- BOOST_FOREACH(auto& in, tx.vin)
+ for(auto& in: tx.vin)
{
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), 0, "unexpected type id in transaction");
amount_in += boost::get<txin_to_key>(in).amount;
}
- BOOST_FOREACH(auto& o, tx.vout)
+ for(auto& o: tx.vout)
amount_out += o.amount;
CHECK_AND_ASSERT_MES(amount_in >= amount_out, false, "transaction spend (" <<amount_in << ") more than it has (" << amount_out << ")");
@@ -540,7 +539,7 @@ namespace cryptonote
uint64_t summary_inputs_money = 0;
//fill inputs
int idx = -1;
- BOOST_FOREACH(const tx_source_entry& src_entr, sources)
+ for(const tx_source_entry& src_entr: sources)
{
++idx;
if(src_entr.real_output >= src_entr.outputs.size())
@@ -574,7 +573,7 @@ namespace cryptonote
input_to_key.k_image = img;
//fill outputs array and use relative offsets
- BOOST_FOREACH(const tx_source_entry::output_entry& out_entry, src_entr.outputs)
+ for(const tx_source_entry::output_entry& out_entry: src_entr.outputs)
input_to_key.key_offsets.push_back(out_entry.first);
input_to_key.key_offsets = absolute_output_offsets_to_relative(input_to_key.key_offsets);
@@ -588,7 +587,7 @@ namespace cryptonote
uint64_t summary_outs_money = 0;
//fill outputs
size_t output_index = 0;
- BOOST_FOREACH(const tx_destination_entry& dst_entr, shuffled_dsts)
+ for(const tx_destination_entry& dst_entr: shuffled_dsts)
{
CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
crypto::key_derivation derivation;
@@ -639,13 +638,13 @@ namespace cryptonote
std::stringstream ss_ring_s;
size_t i = 0;
- BOOST_FOREACH(const tx_source_entry& src_entr, sources)
+ for(const tx_source_entry& src_entr: sources)
{
ss_ring_s << "pub_keys:" << ENDL;
std::vector<const crypto::public_key*> keys_ptrs;
std::vector<crypto::public_key> keys(src_entr.outputs.size());
size_t ii = 0;
- BOOST_FOREACH(const tx_source_entry::output_entry& o, src_entr.outputs)
+ for(const tx_source_entry::output_entry& o: src_entr.outputs)
{
keys[ii] = rct2pk(o.second.dest);
keys_ptrs.push_back(&keys[ii]);
@@ -677,7 +676,7 @@ namespace cryptonote
if (!use_simple_rct)
{
// non simple ringct requires all real inputs to be at the same index for all inputs
- BOOST_FOREACH(const tx_source_entry& src_entr, sources)
+ for(const tx_source_entry& src_entr: sources)
{
if(src_entr.real_output != sources.begin()->real_output)
{
@@ -784,7 +783,7 @@ namespace cryptonote
bool get_inputs_money_amount(const transaction& tx, uint64_t& money)
{
money = 0;
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
money += tokey_in.amount;
@@ -801,7 +800,7 @@ namespace cryptonote
//---------------------------------------------------------------
bool check_inputs_types_supported(const transaction& tx)
{
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECK_AND_ASSERT_MES(in.type() == typeid(txin_to_key), false, "wrong variant type: "
<< in.type().name() << ", expected " << typeid(txin_to_key).name()
@@ -813,7 +812,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool check_outs_valid(const transaction& tx)
{
- BOOST_FOREACH(const tx_out& out, tx.vout)
+ for(const tx_out& out: tx.vout)
{
CHECK_AND_ASSERT_MES(out.target.type() == typeid(txout_to_key), false, "wrong variant type: "
<< out.target.type().name() << ", expected " << typeid(txout_to_key).name()
@@ -838,7 +837,7 @@ namespace cryptonote
bool check_inputs_overflow(const transaction& tx)
{
uint64_t money = 0;
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
if(money > tokey_in.amount + money)
@@ -851,7 +850,7 @@ namespace cryptonote
bool check_outs_overflow(const transaction& tx)
{
uint64_t money = 0;
- BOOST_FOREACH(const auto& o, tx.vout)
+ for(const auto& o: tx.vout)
{
if(money > o.amount + money)
return false;
@@ -863,7 +862,7 @@ namespace cryptonote
uint64_t get_outs_money_amount(const transaction& tx)
{
uint64_t outputs_amount = 0;
- BOOST_FOREACH(const auto& o, tx.vout)
+ for(const auto& o: tx.vout)
outputs_amount += o.amount;
return outputs_amount;
}
@@ -905,7 +904,7 @@ namespace cryptonote
{
money_transfered = 0;
size_t i = 0;
- BOOST_FOREACH(const tx_out& o, tx.vout)
+ for(const tx_out& o: tx.vout)
{
CHECK_AND_ASSERT_MES(o.target.type() == typeid(txout_to_key), false, "wrong type id in transaction out" );
if(is_out_to_acc(acc, boost::get<txout_to_key>(o.target), tx_pub_key, i))
@@ -1177,7 +1176,7 @@ namespace cryptonote
size_t bl_sz = 0;
get_transaction_hash(b.miner_tx, h, bl_sz);
txs_ids.push_back(h);
- BOOST_FOREACH(auto& th, b.tx_hashes)
+ for(auto& th: b.tx_hashes)
txs_ids.push_back(th);
return get_tx_tree_hash(txs_ids);
}
diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp
index 51f508858..88c631f80 100644
--- a/src/cryptonote_core/miner.cpp
+++ b/src/cryptonote_core/miner.cpp
@@ -33,7 +33,6 @@
#include <boost/utility/value_init.hpp>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/limits.hpp>
-#include <boost/foreach.hpp>
#include "misc_language.h"
#include "include_base_utils.h"
#include "cryptonote_basic_impl.h"
@@ -292,7 +291,7 @@ namespace cryptonote
send_stop_signal();
CRITICAL_REGION_LOCAL(m_threads_lock);
- BOOST_FOREACH(boost::thread& th, m_threads)
+ for(boost::thread& th: m_threads)
th.join();
MINFO("Mining has been stopped, " << m_threads.size() << " finished" );
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 6ad139023..e37ddec0d 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -63,7 +63,7 @@ namespace cryptonote
size_t const TRANSACTION_SIZE_LIMIT_V2 = (((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE);
time_t const MIN_RELAY_TIME = (60 * 5); // only start re-relaying transactions after that many seconds
time_t const MAX_RELAY_TIME = (60 * 60 * 4); // at most that many seconds between resends
- float const ACCEPT_THRESHOLD = 0.99f;
+ float const ACCEPT_THRESHOLD = 1.0f;
// a kind of increasing backoff within min/max bounds
time_t get_relay_delay(time_t now, time_t received)
@@ -240,7 +240,7 @@ namespace cryptonote
// assume failure during verification steps until success is certain
tvc.m_verifivation_failed = true;
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false);
std::unordered_set<crypto::hash>& kei_image_set = m_spent_key_images[txin.k_image];
@@ -253,7 +253,7 @@ namespace cryptonote
tvc.m_verifivation_failed = false;
- m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>((double)blob_size / fee, receive_time), id);
+ m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)blob_size, receive_time), id);
return true;
}
@@ -275,7 +275,7 @@ namespace cryptonote
// ND: Speedup
// 1. Move transaction hash calcuation outside of loop. ._.
crypto::hash actual_hash = get_transaction_hash(tx);
- BOOST_FOREACH(const txin_v& vi, tx.vin)
+ for(const txin_v& vi: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
auto it = m_spent_key_images.find(txin.k_image);
@@ -415,7 +415,7 @@ namespace cryptonote
void tx_memory_pool::get_transactions(std::list<transaction>& txs) const
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
- BOOST_FOREACH(const auto& tx_vt, m_transactions)
+ for(const auto& tx_vt: m_transactions)
txs.push_back(tx_vt.second.tx);
}
//------------------------------------------------------------------
@@ -488,7 +488,7 @@ namespace cryptonote
bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx) const
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
- BOOST_FOREACH(const auto& in, tx.vin)
+ for(const auto& in: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, true);//should never fail
if(have_tx_keyimg_as_spent(tokey_in.k_image))
@@ -613,6 +613,10 @@ namespace cryptonote
uint64_t best_coinbase = 0;
total_size = 0;
fee = 0;
+
+ //baseline empty block
+ get_block_reward(median_size, total_size, already_generated_coins, best_coinbase, version);
+
size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
std::unordered_set<crypto::key_image> k_images;
@@ -641,7 +645,7 @@ namespace cryptonote
sorted_it++;
continue;
}
- uint64_t coinbase = block_reward + fee;
+ uint64_t coinbase = block_reward + fee + tx_it->second.fee;
if (coinbase < template_accept_threshold(best_coinbase))
{
LOG_PRINT_L2(" would decrease coinbase to " << print_money(coinbase));
@@ -728,7 +732,7 @@ namespace cryptonote
// no need to store queue of sorted transactions, as it's easy to generate.
for (const auto& tx : m_transactions)
{
- m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>((double)tx.second.blob_size / tx.second.fee, tx.second.receive_time), tx.first);
+ m_txs_by_fee_and_receive_time.emplace(std::pair<double, time_t>(tx.second.fee / (double)tx.second.blob_size, tx.second.receive_time), tx.first);
}
// Ignore deserialization error
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
index 56b82ed15..09c202e79 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler-base.cpp
@@ -52,7 +52,6 @@
#include "../../contrib/epee/include/net/net_utils_base.h"
#include "../../contrib/epee/include/misc_log_ex.h"
#include <boost/lambda/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/chrono.hpp>
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index 73e4fa72f..1309ff742 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -411,7 +411,7 @@ namespace cryptonote
transaction tx;
crypto::hash tx_hash;
- BOOST_FOREACH(auto& tx_blob, arg.b.txs)
+ for(auto& tx_blob: arg.b.txs)
{
if(parse_and_validate_tx_from_blob(tx_blob, tx))
{
@@ -527,7 +527,7 @@ namespace cryptonote
}
size_t tx_idx = 0;
- BOOST_FOREACH(auto& tx_hash, new_block.tx_hashes)
+ for(auto& tx_hash: new_block.tx_hashes)
{
if(m_core.get_pool_transaction(tx_hash, tx))
{
@@ -638,7 +638,7 @@ namespace cryptonote
fluffy_response.current_blockchain_height = m_core.get_current_blockchain_height();
fluffy_response.hop = arg.hop;
size_t local_txs_count = local_txs.size();
- BOOST_FOREACH(auto& tx_idx, arg.missing_tx_indices)
+ for(auto& tx_idx: arg.missing_tx_indices)
{
if(tx_idx < local_txs_count)
{
@@ -790,7 +790,7 @@ namespace cryptonote
context.m_remote_blockchain_height = arg.current_blockchain_height;
size_t count = 0;
- BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks)
+ for(const block_complete_entry& block_entry: arg.blocks)
{
if (m_stopping)
{
@@ -859,7 +859,7 @@ namespace cryptonote
uint64_t previous_height = m_core.get_current_blockchain_height();
m_core.prepare_handle_incoming_blocks(arg.blocks);
- BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks)
+ for(const block_complete_entry& block_entry: arg.blocks)
{
if (m_stopping)
{
@@ -869,7 +869,7 @@ namespace cryptonote
// process transactions
TIME_MEASURE_START(transactions_process_time);
- BOOST_FOREACH(auto& tx_blob, block_entry.txs)
+ for(auto& tx_blob: block_entry.txs)
{
tx_verification_context tvc = AUTO_VAL_INIT(tvc);
m_core.handle_incoming_tx(tx_blob, tvc, true, true, false);
@@ -1077,7 +1077,7 @@ namespace cryptonote
m_p2p->drop_connection(context);
}
- BOOST_FOREACH(auto& bl_id, arg.m_block_ids)
+ for(auto& bl_id: arg.m_block_ids)
{
if(!m_core.have_block(bl_id))
context.m_needed_objects.push_back(bl_id);
diff --git a/src/daemon/protocol.h b/src/daemon/protocol.h
index bc2333659..5bcb83dcf 100644
--- a/src/daemon/protocol.h
+++ b/src/daemon/protocol.h
@@ -77,6 +77,7 @@ public:
m_protocol.deinit();
m_protocol.set_p2p_endpoint(nullptr);
MGINFO("Cryptonote protocol stopped successfully");
+ tools::success_msg_writer() << "Daemon stopped successfully";
} catch (...) {
LOG_ERROR("Failed to stop cryptonote protocol!");
}
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 8558ebc17..7bc9afbb9 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -1451,6 +1451,7 @@ bool t_rpc_command_executor::print_blockchain_dynamic_stats(uint64_t nblocks)
std::string fail_message = "Problem fetching info";
+ fereq.grace_blocks = 0;
if (m_is_rpc)
{
if (!m_rpc_client->rpc_request(ireq, ires, "/getinfo", fail_message.c_str()))
diff --git a/src/p2p/connection_basic.cpp b/src/p2p/connection_basic.cpp
index 80915e9a3..bdb239ca8 100644
--- a/src/p2p/connection_basic.cpp
+++ b/src/p2p/connection_basic.cpp
@@ -56,7 +56,6 @@
#include "../../contrib/epee/include/net/net_utils_base.h"
#include "../../contrib/epee/include/misc_log_ex.h"
#include <boost/lambda/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/chrono.hpp>
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index 40598fc0f..5ed96c00b 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -31,7 +31,6 @@
#pragma once
#include <boost/thread.hpp>
#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/bimap.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 0e43d9579..d67c5dd93 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -1182,7 +1182,7 @@ namespace nodetool
time(&now);
delta = now - local_time;
- BOOST_FOREACH(peerlist_entry& be, local_peerlist)
+ for(peerlist_entry& be: local_peerlist)
{
if(be.last_seen > local_time)
{
@@ -1320,7 +1320,7 @@ namespace nodetool
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::relay_notify_to_list(int command, const std::string& data_buff, const std::list<boost::uuids::uuid> &connections)
{
- BOOST_FOREACH(const auto& c_id, connections)
+ for(const auto& c_id: connections)
{
m_net_server.get_config_object().notify(command, data_buff, c_id);
}
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index 160206ed3..c73d6615d 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -33,7 +33,6 @@
#include <list>
#include <set>
#include <map>
-#include <boost/foreach.hpp>
//#include <boost/bimap.hpp>
//#include <boost/bimap/multiset_of.hpp>
#include <boost/archive/binary_iarchive.hpp>
@@ -45,6 +44,7 @@
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
+#include <boost/range/adaptor/reversed.hpp>
#include "syncobj.h"
@@ -230,7 +230,7 @@ namespace nodetool
bool peerlist_manager::merge_peerlist(const std::list<peerlist_entry>& outer_bs)
{
CRITICAL_REGION_LOCAL(m_peerlist_lock);
- BOOST_FOREACH(const peerlist_entry& be, outer_bs)
+ for(const peerlist_entry& be: outer_bs)
{
append_with_peer_gray(be);
}
@@ -283,7 +283,7 @@ namespace nodetool
CRITICAL_REGION_LOCAL(m_peerlist_lock);
peers_indexed::index<by_time>::type& by_time_index=m_peers_white.get<by_time>();
uint32_t cnt = 0;
- BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index)
+ for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index))
{
if(!vl.last_seen)
continue;
@@ -301,13 +301,13 @@ namespace nodetool
{
CRITICAL_REGION_LOCAL(m_peerlist_lock);
peers_indexed::index<by_time>::type& by_time_index_gr=m_peers_gray.get<by_time>();
- BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index_gr)
+ for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_gr))
{
pl_gray.push_back(vl);
}
peers_indexed::index<by_time>::type& by_time_index_wt=m_peers_white.get<by_time>();
- BOOST_REVERSE_FOREACH(const peers_indexed::value_type& vl, by_time_index_wt)
+ for(const peers_indexed::value_type& vl: boost::adaptors::reverse(by_time_index_wt))
{
pl_white.push_back(vl);
}
diff --git a/src/p2p/network_throttle-detail.cpp b/src/p2p/network_throttle-detail.cpp
index 9efaaf95a..d4fe356a9 100644
--- a/src/p2p/network_throttle-detail.cpp
+++ b/src/p2p/network_throttle-detail.cpp
@@ -54,7 +54,6 @@
#include "../../contrib/epee/include/net/net_utils_base.h"
#include "../../contrib/epee/include/misc_log_ex.h"
#include <boost/lambda/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/chrono.hpp>
diff --git a/src/p2p/network_throttle.hpp b/src/p2p/network_throttle.hpp
index b954c5b3a..4f6cbe9cf 100644
--- a/src/p2p/network_throttle.hpp
+++ b/src/p2p/network_throttle.hpp
@@ -57,7 +57,6 @@
#include "../../contrib/epee/include/net/net_utils_base.h"
#include "../../contrib/epee/include/misc_log_ex.h"
#include <boost/lambda/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/uuid/random_generator.hpp>
#include <boost/chrono.hpp>
diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h
index ce1ee1449..6d6ac7b98 100644
--- a/src/p2p/p2p_protocol_defs.h
+++ b/src/p2p/p2p_protocol_defs.h
@@ -83,7 +83,7 @@ namespace nodetool
time(&now_time);
std::stringstream ss;
ss << std::setfill ('0') << std::setw (8) << std::hex << std::noshowbase;
- BOOST_FOREACH(const peerlist_entry& pe, pl)
+ for(const peerlist_entry& pe: pl)
{
ss << pe.id << "\t" << epee::string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port) << " \tlast_seen: " << epee::misc_utils::get_time_interval_string(now_time - pe.last_seen) << std::endl;
}
diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h
index b1aa243b9..0c27745e1 100644
--- a/src/ringct/rctTypes.h
+++ b/src/ringct/rctTypes.h
@@ -40,11 +40,11 @@
#include <cinttypes>
extern "C" {
-#include "crypto/generic-ops.h"
#include "crypto/crypto-ops.h"
#include "crypto/random.h"
#include "crypto/keccak.h"
}
+#include "crypto/generic-ops.h"
#include "crypto/crypto.h"
#include "serialization/serialization.h"
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 7d896e491..b2e8e6716 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -28,7 +28,6 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
-#include <boost/foreach.hpp>
#include "include_base_utils.h"
using namespace epee;
@@ -160,7 +159,7 @@ namespace cryptonote
return false;
}
- BOOST_FOREACH(auto& b, bs)
+ for(auto& b: bs)
{
res.blocks.resize(res.blocks.size()+1);
res.blocks.back().block = block_to_blob(b.first);
@@ -173,7 +172,7 @@ namespace cryptonote
return false;
}
size_t txidx = 0;
- BOOST_FOREACH(auto& t, b.second)
+ for(auto& t: b.second)
{
res.blocks.back().txs.push_back(tx_to_blob(t));
res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices());
@@ -205,7 +204,7 @@ namespace cryptonote
}
catch (...)
{
- res.status = "Error retrieving block at height " + height;
+ res.status = "Error retrieving block at height " + std::to_string(height);
return true;
}
std::list<transaction> txs;
@@ -381,7 +380,7 @@ namespace cryptonote
{
CHECK_CORE_BUSY();
std::vector<crypto::hash> vh;
- BOOST_FOREACH(const auto& tx_hex_str, req.txs_hashes)
+ for(const auto& tx_hex_str: req.txs_hashes)
{
blobdata b;
if(!string_tools::parse_hexstr_to_binbuff(tx_hex_str, b))
@@ -433,7 +432,7 @@ namespace cryptonote
std::list<std::string>::const_iterator txhi = req.txs_hashes.begin();
std::vector<crypto::hash>::const_iterator vhi = vh.begin();
- BOOST_FOREACH(auto& tx, txs)
+ for(auto& tx: txs)
{
res.txs.push_back(COMMAND_RPC_GET_TRANSACTIONS::entry());
COMMAND_RPC_GET_TRANSACTIONS::entry &e = res.txs.back();
@@ -471,7 +470,7 @@ namespace cryptonote
}
}
- BOOST_FOREACH(const auto& miss_tx, missed_txs)
+ for(const auto& miss_tx: missed_txs)
{
res.missed_tx.push_back(string_tools::pod_to_hex(miss_tx));
}
@@ -485,7 +484,7 @@ namespace cryptonote
{
CHECK_CORE_BUSY();
std::vector<crypto::key_image> key_images;
- BOOST_FOREACH(const auto& ki_hex_str, req.key_images)
+ for(const auto& ki_hex_str: req.key_images)
{
blobdata b;
if(!string_tools::parse_hexstr_to_binbuff(ki_hex_str, b))
@@ -616,6 +615,23 @@ namespace cryptonote
return true;
}
+ unsigned int concurrency_count = boost::thread::hardware_concurrency() * 4;
+
+ // if we couldn't detect threads, set it to a ridiculously high number
+ if(concurrency_count == 0)
+ {
+ concurrency_count = 257;
+ }
+
+ // if there are more threads requested than the hardware supports
+ // then we fail and log that.
+ if(req.threads_count > concurrency_count)
+ {
+ res.status = "Failed, too many threads relative to CPU cores.";
+ LOG_PRINT_L0(res.status);
+ return true;
+ }
+
boost::thread::attributes attrs;
attrs.set_stack_size(THREAD_STACK_SIZE);
@@ -908,7 +924,7 @@ namespace cryptonote
uint64_t core_rpc_server::get_block_reward(const block& blk)
{
uint64_t reward = 0;
- BOOST_FOREACH(const tx_out& out, blk.miner_tx.vout)
+ for(const tx_out& out: blk.miner_tx.vout)
{
reward += out.amount;
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 50509040c..8fc2559bd 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -362,6 +362,33 @@ bool simple_wallet::seed_set_language(const std::vector<std::string> &args/* = s
return true;
}
+bool simple_wallet::change_password(const std::vector<std::string> &args)
+{
+ const auto orig_pwd_container = get_and_verify_password();
+
+ if(orig_pwd_container == boost::none)
+ {
+ fail_msg_writer() << tr("Your original password was incorrect.");
+ return false;
+ }
+
+ // prompts for a new password, this is not a new wallet so pass in false.
+ const auto pwd_container = tools::wallet2::password_prompt(false);
+
+ try
+ {
+ m_wallet->rewrite(m_wallet_file, pwd_container->password());
+ m_wallet->store();
+ }
+ catch (const wallet_logic_error& e)
+ {
+ fail_msg_writer() << tr("Error with wallet rewrite: ") << e.what();
+ return false;
+ }
+
+ return true;
+}
+
bool simple_wallet::set_always_confirm_transfers(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
@@ -1163,6 +1190,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
}
catch (const std::exception &e) { }
+ m_http_client.set_server(m_wallet->get_daemon_address());
m_wallet->callback(this);
return true;
}
@@ -1560,7 +1588,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args)
}
COMMAND_RPC_START_MINING::response res;
- bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/start_mining", req, res, m_http_client);
+ bool r = net_utils::invoke_http_json("/start_mining", req, res, m_http_client);
std::string err = interpret_rpc_response(r, res.status);
if (err.empty())
success_msg_writer() << tr("Mining started in daemon");
@@ -1577,7 +1605,7 @@ bool simple_wallet::stop_mining(const std::vector<std::string>& args)
assert(m_wallet);
COMMAND_RPC_STOP_MINING::request req;
COMMAND_RPC_STOP_MINING::response res;
- bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/stop_mining", req, res, m_http_client);
+ bool r = net_utils::invoke_http_json("/stop_mining", req, res, m_http_client);
std::string err = interpret_rpc_response(r, res.status);
if (err.empty())
success_msg_writer() << tr("Mining stopped in daemon");
@@ -1594,7 +1622,7 @@ bool simple_wallet::save_bc(const std::vector<std::string>& args)
assert(m_wallet);
COMMAND_RPC_SAVE_BC::request req;
COMMAND_RPC_SAVE_BC::response res;
- bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/save_bc", req, res, m_http_client);
+ bool r = net_utils::invoke_http_json("/save_bc", req, res, m_http_client);
std::string err = interpret_rpc_response(r, res.status);
if (err.empty())
success_msg_writer() << tr("Blockchain saved");
@@ -1883,7 +1911,7 @@ uint64_t simple_wallet::get_daemon_blockchain_height(std::string& err)
COMMAND_RPC_GET_HEIGHT::request req;
COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized<COMMAND_RPC_GET_HEIGHT::response>();
- bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/getheight", req, res, m_http_client);
+ bool r = net_utils::invoke_http_json("/getheight", req, res, m_http_client);
err = interpret_rpc_response(r, res.status);
return res.height;
}
@@ -1994,7 +2022,7 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
req.outputs[j].index = absolute_offsets[j];
}
COMMAND_RPC_GET_OUTPUTS_BIN::response res = AUTO_VAL_INIT(res);
- bool r = net_utils::invoke_http_bin_remote_command2(m_wallet->get_daemon_address() + "/get_outs.bin", req, res, m_http_client);
+ bool r = net_utils::invoke_http_bin("/get_outs.bin", req, res, m_http_client);
err = interpret_rpc_response(r, res.status);
if (!err.empty())
{
@@ -2143,7 +2171,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
cryptonote::tx_destination_entry de;
bool has_payment_id;
crypto::hash8 new_payment_id;
- if (!tools::dns_utils::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i]))
+ if (!cryptonote::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i]))
return true;
if (has_payment_id)
@@ -2636,7 +2664,7 @@ bool simple_wallet::sweep_all(const std::vector<std::string> &args_)
bool has_payment_id;
crypto::hash8 new_payment_id;
cryptonote::account_public_address address;
- if (!tools::dns_utils::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0]))
+ if (!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0]))
return true;
if (has_payment_id)
@@ -3187,7 +3215,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!tools::dns_utils::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2]))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -3196,7 +3224,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
COMMAND_RPC_GET_TRANSACTIONS::request req;
COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid));
- if (!net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/gettransactions", req, res, m_http_client) ||
+ if (!net_utils::invoke_http_json("/gettransactions", req, res, m_http_client) ||
(res.txs.size() != 1 && res.txs_as_hex.size() != 1))
{
fail_msg_writer() << tr("failed to get transaction from daemon");
@@ -3735,7 +3763,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id8;
- if(!tools::dns_utils::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1]))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -3925,7 +3953,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!tools::dns_utils::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string))
{
fail_msg_writer() << tr("failed to parse address");
return true;
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index 237c1e3e1..9918300df 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -162,6 +162,7 @@ namespace cryptonote
bool export_outputs(const std::vector<std::string> &args);
bool import_outputs(const std::vector<std::string> &args);
bool show_transfer(const std::vector<std::string> &args);
+ bool change_password(const std::vector<std::string>& args);
uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon(bool silent = false, uint32_t* version = nullptr);
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 52ecc2e6a..9e40d2e02 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -197,6 +197,44 @@ bool Wallet::addressValid(const std::string &str, bool testnet)
return get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, str);
}
+bool Wallet::keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error)
+{
+ bool has_payment_id;
+ cryptonote::account_public_address address;
+ crypto::hash8 pid;
+ if(!get_account_integrated_address_from_str(address, has_payment_id, pid, testnet, address_string)) {
+ error = tr("Failed to parse address");
+ return false;
+ }
+
+ cryptonote::blobdata key_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(secret_key_string, key_data) || key_data.size() != sizeof(crypto::secret_key))
+ {
+ error = tr("Failed to parse key");
+ return false;
+ }
+ crypto::secret_key key = *reinterpret_cast<const crypto::secret_key*>(key_data.data());
+
+ // check the key match the given address
+ crypto::public_key pkey;
+ if (!crypto::secret_key_to_public_key(key, pkey)) {
+ error = tr("failed to verify key");
+ return false;
+ }
+ bool matchAddress = false;
+ if(isViewKey)
+ matchAddress = address.m_view_public_key == pkey;
+ else
+ matchAddress = address.m_spend_public_key == pkey;
+
+ if(!matchAddress) {
+ error = tr("key does not match address");
+ return false;
+ }
+
+ return true;
+}
+
std::string Wallet::paymentIdFromAddress(const std::string &str, bool testnet)
{
bool has_payment_id;
@@ -337,6 +375,98 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas
return true;
}
+bool WalletImpl::recoverFromKeys(const std::string &path,
+ const std::string &language,
+ const std::string &address_string,
+ const std::string &viewkey_string,
+ const std::string &spendkey_string)
+{
+ cryptonote::account_public_address address;
+ bool has_payment_id;
+ crypto::hash8 new_payment_id;
+ if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, m_wallet->testnet(), address_string))
+ {
+ m_errorString = tr("failed to parse address");
+ m_status = Status_Error;
+ return false;
+ }
+
+ // parse optional spend key
+ crypto::secret_key spendkey;
+ bool has_spendkey = false;
+ if (!spendkey_string.empty()) {
+ cryptonote::blobdata spendkey_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key))
+ {
+ m_errorString = tr("failed to parse secret spend key");
+ m_status = Status_Error;
+ return false;
+ }
+ has_spendkey = true;
+ spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
+ }
+
+ // parse view secret key
+ if (viewkey_string.empty()) {
+ m_errorString = tr("No view key supplied, cancelled");
+ m_status = Status_Error;
+ return false;
+ }
+ cryptonote::blobdata viewkey_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key))
+ {
+ m_errorString = tr("failed to parse secret view key");
+ m_status = Status_Error;
+ return false;
+ }
+ crypto::secret_key viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
+
+ // check the spend and view keys match the given address
+ crypto::public_key pkey;
+ if(has_spendkey) {
+ if (!crypto::secret_key_to_public_key(spendkey, pkey)) {
+ m_errorString = tr("failed to verify secret spend key");
+ m_status = Status_Error;
+ return false;
+ }
+ if (address.m_spend_public_key != pkey) {
+ m_errorString = tr("spend key does not match address");
+ m_status = Status_Error;
+ return false;
+ }
+ }
+ if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
+ m_errorString = tr("failed to verify secret view key");
+ m_status = Status_Error;
+ return false;
+ }
+ if (address.m_view_public_key != pkey) {
+ m_errorString = tr("view key does not match address");
+ m_status = Status_Error;
+ return false;
+ }
+
+ try
+ {
+ if (has_spendkey) {
+ m_wallet->generate(path, "", address, spendkey, viewkey);
+ LOG_PRINT_L1("Generated new wallet from keys");
+ }
+ else {
+ m_wallet->generate(path, "", address, viewkey);
+ LOG_PRINT_L1("Generated new view only wallet from keys");
+ }
+
+ }
+ catch (const std::exception& e) {
+ m_errorString = string(tr("failed to generate new wallet: ")) + e.what();
+ m_status = Status_Error;
+ return false;
+ }
+ return true;
+}
+
+
bool WalletImpl::open(const std::string &path, const std::string &password)
{
clearStatus();
@@ -516,12 +646,12 @@ string WalletImpl::keysFilename() const
bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transaction_size_limit)
{
clearStatus();
- doInit(daemon_address, upper_transaction_size_limit);
+ if (!doInit(daemon_address, upper_transaction_size_limit))
+ return false;
bool result = this->refresh();
// enabling background refresh thread
startRefresh();
return result;
-
}
void WalletImpl::initAsync(const string &daemon_address, uint64_t upper_transaction_size_limit)
@@ -1232,9 +1362,10 @@ bool WalletImpl::isNewWallet() const
return !(blockChainHeight() > 1 || m_recoveringFromSeed || m_rebuildWalletCache) && !watchOnly();
}
-void WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit)
+bool WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit)
{
- m_wallet->init(daemon_address, upper_transaction_size_limit);
+ if (!m_wallet->init(daemon_address, upper_transaction_size_limit))
+ return false;
// in case new wallet, this will force fast-refresh (pulling hashes instead of blocks)
// If daemon isn't synced a calculated block height will be used instead
@@ -1253,8 +1384,7 @@ void WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction
this->setTrustedDaemon(false);
m_refreshIntervalMillis = DEFAULT_REMOTE_NODE_REFRESH_INTERVAL_MILLIS;
}
-
-
+ return true;
}
bool WalletImpl::parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error)
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index bee2342a2..7daf63e43 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -58,6 +58,11 @@ public:
const std::string &language) const;
bool open(const std::string &path, const std::string &password);
bool recover(const std::string &path, const std::string &seed);
+ bool recoverFromKeys(const std::string &path,
+ const std::string &language,
+ const std::string &address_string,
+ const std::string &viewkey_string,
+ const std::string &spendkey_string = "");
bool close();
std::string seed() const;
std::string getSeedLanguage() const;
@@ -128,7 +133,7 @@ private:
bool daemonSynced() const;
void stopRefresh();
bool isNewWallet() const;
- void doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit);
+ bool doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit);
private:
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index 904338a72..c761cc6d2 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -43,6 +43,15 @@ namespace epee {
unsigned int g_test_dbg_lock_sleep = 0;
}
+namespace {
+ template<typename Request, typename Response>
+ bool connect_and_invoke(const std::string& address, const std::string& path, const Request& request, Response& response)
+ {
+ epee::net_utils::http::http_simple_client client{};
+ return client.set_server(address) && epee::net_utils::invoke_http_json(path, request, response, client);
+ }
+}
+
namespace Monero {
Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password,
@@ -72,6 +81,22 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, const std::st
return wallet;
}
+Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
+ const std::string &language,
+ bool testnet,
+ uint64_t restoreHeight,
+ const std::string &addressString,
+ const std::string &viewKeyString,
+ const std::string &spendKeyString)
+{
+ WalletImpl * wallet = new WalletImpl(testnet);
+ if(restoreHeight > 0){
+ wallet->setRefreshFromBlockHeight(restoreHeight);
+ }
+ wallet->recoverFromKeys(path, language, addressString, viewKeyString, spendKeyString);
+ return wallet;
+}
+
bool WalletManagerImpl::closeWallet(Wallet *wallet)
{
WalletImpl * wallet_ = dynamic_cast<WalletImpl*>(wallet);
@@ -145,9 +170,7 @@ bool WalletManagerImpl::connected(uint32_t *version) const
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_version";
- epee::net_utils::http::http_simple_client http_client;
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/json_rpc", req_t, resp_t, http_client);
- if (!r)
+ if (!connect_and_invoke(m_daemonAddress, "/json_rpc", req_t, resp_t))
return false;
if (version)
@@ -193,8 +216,7 @@ bool WalletManagerImpl::checkPayment(const std::string &address_text, const std:
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req;
cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid));
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(daemon_address + "/gettransactions", req, res, http_client) ||
+ if (!connect_and_invoke(m_daemonAddress, "/gettransactions", req, res) ||
(res.txs.size() != 1 && res.txs_as_hex.size() != 1))
{
error = tr("failed to get transaction from daemon");
@@ -312,8 +334,7 @@ uint64_t WalletManagerImpl::blockchainHeight() const
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
cryptonote::COMMAND_RPC_GET_INFO::response ires;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/getinfo", ireq, ires, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires))
return 0;
return ires.height;
}
@@ -323,8 +344,7 @@ uint64_t WalletManagerImpl::blockchainTargetHeight() const
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
cryptonote::COMMAND_RPC_GET_INFO::response ires;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/getinfo", ireq, ires, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires))
return 0;
return ires.target_height >= ires.height ? ires.target_height : ires.height;
}
@@ -334,8 +354,7 @@ uint64_t WalletManagerImpl::networkDifficulty() const
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
cryptonote::COMMAND_RPC_GET_INFO::response ires;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/getinfo", ireq, ires, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires))
return 0;
return ires.difficulty;
}
@@ -346,7 +365,7 @@ double WalletManagerImpl::miningHashRate() const
cryptonote::COMMAND_RPC_MINING_STATUS::response mres;
epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/mining_status", mreq, mres, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/mining_status", mreq, mres))
return 0.0;
if (!mres.active)
return 0.0;
@@ -366,7 +385,7 @@ void WalletManagerImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "hard_fork_info";
req_t.params.version = 0;
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/json_rpc", req_t, resp_t, http_client);
+ bool r = connect_and_invoke(m_daemonAddress, "/json_rpc", req_t, resp_t);
if (!r || resp_t.result.status != CORE_RPC_STATUS_OK)
return;
version = resp_t.result.version;
@@ -378,8 +397,7 @@ uint64_t WalletManagerImpl::blockTarget() const
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
cryptonote::COMMAND_RPC_GET_INFO::response ires;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/getinfo", ireq, ires, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/getinfo", ireq, ires))
return 0;
return ires.target;
}
@@ -389,8 +407,7 @@ bool WalletManagerImpl::isMining() const
cryptonote::COMMAND_RPC_MINING_STATUS::request mreq;
cryptonote::COMMAND_RPC_MINING_STATUS::response mres;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/mining_status", mreq, mres, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/mining_status", mreq, mres))
return false;
return mres.active;
}
@@ -403,8 +420,7 @@ bool WalletManagerImpl::startMining(const std::string &address, uint32_t threads
mreq.miner_address = address;
mreq.threads_count = threads;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/start_mining", mreq, mres, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/start_mining", mreq, mres))
return false;
return mres.status == CORE_RPC_STATUS_OK;
}
@@ -414,8 +430,7 @@ bool WalletManagerImpl::stopMining()
cryptonote::COMMAND_RPC_STOP_MINING::request mreq;
cryptonote::COMMAND_RPC_STOP_MINING::response mres;
- epee::net_utils::http::http_simple_client http_client;
- if (!epee::net_utils::invoke_http_json_remote_command2(m_daemonAddress + "/stop_mining", mreq, mres, http_client))
+ if (!connect_and_invoke(m_daemonAddress, "/stop_mining", mreq, mres))
return false;
return mres.status == CORE_RPC_STATUS_OK;
}
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index ca9570254..ce9b70e96 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -41,6 +41,13 @@ public:
const std::string &language, bool testnet);
Wallet * openWallet(const std::string &path, const std::string &password, bool testnet);
virtual Wallet * recoveryWallet(const std::string &path, const std::string &memo, bool testnet, uint64_t restoreHeight);
+ virtual Wallet * createWalletFromKeys(const std::string &path,
+ const std::string &language,
+ bool testnet,
+ uint64_t restoreHeight,
+ const std::string &addressString,
+ const std::string &viewKeyString,
+ const std::string &spendKeyString = "");
virtual bool closeWallet(Wallet *wallet);
bool walletExists(const std::string &path);
std::vector<std::string> findWallets(const std::string &path);
diff --git a/src/wallet/node_rpc_proxy.cpp b/src/wallet/node_rpc_proxy.cpp
index d7f755e36..cc249b5cc 100644
--- a/src/wallet/node_rpc_proxy.cpp
+++ b/src/wallet/node_rpc_proxy.cpp
@@ -36,18 +36,16 @@ using namespace epee;
namespace tools
{
-void NodeRPCProxy::init(const std::string &daemon_address)
-{
- m_daemon_address = daemon_address;
-
- m_height = 0;
- m_height_time = 0;
- for (auto &slot: m_earliest_height)
- slot = 0;
- m_dynamic_per_kb_fee_estimate = 0;
- m_dynamic_per_kb_fee_estimate_cached_height = 0;
- m_dynamic_per_kb_fee_estimate_grace_blocks = 0;
-}
+NodeRPCProxy::NodeRPCProxy(epee::net_utils::http::http_simple_client &http_client, boost::mutex &mutex)
+ : m_http_client(http_client)
+ , m_daemon_rpc_mutex(mutex)
+ , m_height(0)
+ , m_height_time(0)
+ , m_earliest_height()
+ , m_dynamic_per_kb_fee_estimate(0)
+ , m_dynamic_per_kb_fee_estimate_cached_height(0)
+ , m_dynamic_per_kb_fee_estimate_grace_blocks(0)
+{}
boost::optional<std::string> NodeRPCProxy::get_height(uint64_t &height)
{
@@ -58,7 +56,7 @@ boost::optional<std::string> NodeRPCProxy::get_height(uint64_t &height)
cryptonote::COMMAND_RPC_GET_HEIGHT::response res = AUTO_VAL_INIT(res);
m_daemon_rpc_mutex.lock();
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/getheight", req, res, m_http_client);
+ bool r = net_utils::invoke_http_json("/getheight", req, res, m_http_client);
m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, res.status, "Failed to connect to daemon");
@@ -87,7 +85,7 @@ boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version,
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "hard_fork_info";
req_t.params.version = version;
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon");
@@ -117,7 +115,7 @@ boost::optional<std::string> NodeRPCProxy::get_dynamic_per_kb_fee_estimate(uint6
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_fee_estimate";
req_t.params.grace_blocks = grace_blocks;
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, resp_t.result.status, "Failed to connect to daemon");
diff --git a/src/wallet/node_rpc_proxy.h b/src/wallet/node_rpc_proxy.h
index 1ae716dab..e2f42d541 100644
--- a/src/wallet/node_rpc_proxy.h
+++ b/src/wallet/node_rpc_proxy.h
@@ -39,10 +39,7 @@ namespace tools
class NodeRPCProxy
{
public:
- NodeRPCProxy(epee::net_utils::http::http_simple_client &http_client, boost::mutex &mutex):
- m_http_client(http_client), m_daemon_rpc_mutex(mutex) { init(""); }
-
- void init(const std::string &daemon_address);
+ NodeRPCProxy(epee::net_utils::http::http_simple_client &http_client, boost::mutex &mutex);
boost::optional<std::string> get_height(uint64_t &height);
void set_height(uint64_t h);
@@ -50,7 +47,6 @@ public:
boost::optional<std::string> get_dynamic_per_kb_fee_estimate(uint64_t grace_blocks, uint64_t &fee);
private:
- std::string m_daemon_address;
epee::net_utils::http::http_simple_client &m_http_client;
boost::mutex &m_daemon_rpc_mutex;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 4348b8a62..9fd98056a 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -164,7 +164,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port);
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(testnet, restricted));
- wallet->init(daemon_address);
+ wallet->init(std::move(daemon_address));
return wallet;
}
@@ -418,6 +418,7 @@ namespace tools
// for now, limit to 30 attempts. TODO: discuss a good number to limit to.
const size_t MAX_SPLIT_ATTEMPTS = 30;
+constexpr const std::chrono::seconds wallet2::rpc_timeout;
const char* wallet2::tr(const char* str) { return i18n_translate(str, "tools::wallet2"); }
bool wallet2::has_testnet_option(const boost::program_options::variables_map& vm)
@@ -484,11 +485,11 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const
}
//----------------------------------------------------------------------------------------------------
-void wallet2::init(const std::string& daemon_address, uint64_t upper_transaction_size_limit)
+bool wallet2::init(std::string daemon_address, uint64_t upper_transaction_size_limit)
{
m_upper_transaction_size_limit = upper_transaction_size_limit;
- m_daemon_address = daemon_address;
- m_node_rpc_proxy.init(m_daemon_address);
+ m_daemon_address = std::move(daemon_address);
+ return m_http_client.set_server(get_daemon_address());
}
//----------------------------------------------------------------------------------------------------
bool wallet2::is_deterministic() const
@@ -841,7 +842,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
" not match with daemon response size=" + std::to_string(o_indices.size()));
}
- BOOST_FOREACH(size_t o, outs)
+ for(size_t o: outs)
{
THROW_WALLET_EXCEPTION_IF(tx.vout.size() <= o, error::wallet_internal_error, "wrong out in transaction: internal index=" +
std::to_string(o) + ", total_outs=" + std::to_string(tx.vout.size()));
@@ -945,7 +946,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, const s
uint64_t tx_money_spent_in_ins = 0;
// check all outputs for spending (compare key images)
- BOOST_FOREACH(auto& in, tx.vin)
+ for(auto& in: tx.vin)
{
if(in.type() != typeid(cryptonote::txin_to_key))
continue;
@@ -1106,7 +1107,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry
TIME_MEASURE_FINISH(miner_tx_handle_time);
TIME_MEASURE_START(txs_handle_time);
- BOOST_FOREACH(auto& txblob, bche.txs)
+ for(auto& txblob: bche.txs)
{
cryptonote::transaction tx;
bool r = parse_and_validate_tx_from_blob(txblob, tx);
@@ -1169,7 +1170,7 @@ void wallet2::pull_blocks(uint64_t start_height, uint64_t &blocks_start_height,
req.start_height = start_height;
m_daemon_rpc_mutex.lock();
- bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getblocks.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
+ bool r = net_utils::invoke_http_bin("/getblocks.bin", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getblocks.bin");
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getblocks.bin");
@@ -1191,7 +1192,7 @@ void wallet2::pull_hashes(uint64_t start_height, uint64_t &blocks_start_height,
req.start_height = start_height;
m_daemon_rpc_mutex.lock();
- bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/gethashes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT);
+ bool r = net_utils::invoke_http_bin("/gethashes.bin", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "gethashes.bin");
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "gethashes.bin");
@@ -1275,7 +1276,7 @@ void wallet2::process_blocks(uint64_t start_height, const std::list<cryptonote::
}
else
{
- BOOST_FOREACH(auto& bl_entry, blocks)
+ for(auto& bl_entry: blocks)
{
cryptonote::block bl;
bool r = cryptonote::parse_and_validate_block_from_blob(bl_entry.block, bl);
@@ -1353,7 +1354,7 @@ void wallet2::update_pool_state()
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req;
cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res;
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/get_transaction_pool", req, res, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_json("/get_transaction_pool", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_transaction_pool");
THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_transaction_pool");
@@ -1461,7 +1462,7 @@ void wallet2::update_pool_state()
req.txs_hashes.push_back(it.id_hash);
req.decode_as_json = false;
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_json("/gettransactions", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
if (r && res.status == CORE_RPC_STATUS_OK)
{
@@ -1556,7 +1557,7 @@ void wallet2::fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height,
}
}
current_index = blocks_start_height;
- BOOST_FOREACH(auto& bl_id, hashes)
+ for(auto& bl_id: hashes)
{
if(current_index >= m_blockchain.size())
{
@@ -2262,15 +2263,7 @@ bool wallet2::check_connection(uint32_t *version, uint32_t timeout)
if(!m_http_client.is_connected())
{
- net_utils::http::url_content u;
- net_utils::parse_url(m_daemon_address, u);
-
- if(!u.port)
- {
- u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
- }
-
- if (!m_http_client.connect(u.host, std::to_string(u.port), timeout))
+ if (!m_http_client.connect(std::chrono::milliseconds(timeout)))
return false;
}
@@ -2281,7 +2274,7 @@ bool wallet2::check_connection(uint32_t *version, uint32_t timeout)
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_version";
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
if (!r || resp_t.result.status != CORE_RPC_STATUS_OK)
*version = 0;
else
@@ -2514,7 +2507,7 @@ void wallet2::store_to(const std::string &path, const std::string &password)
uint64_t wallet2::unlocked_balance() const
{
uint64_t amount = 0;
- BOOST_FOREACH(const transfer_details& td, m_transfers)
+ for(const transfer_details& td: m_transfers)
if(!td.m_spent && is_transfer_unlocked(td))
amount += td.amount();
@@ -2524,12 +2517,12 @@ uint64_t wallet2::unlocked_balance() const
uint64_t wallet2::balance() const
{
uint64_t amount = 0;
- BOOST_FOREACH(auto& td, m_transfers)
+ for(auto& td: m_transfers)
if(!td.m_spent)
amount += td.amount();
- BOOST_FOREACH(auto& utx, m_unconfirmed_txs)
+ for(auto& utx: m_unconfirmed_txs)
if (utx.second.m_state != wallet2::unconfirmed_transfer_details::failed)
amount+= utx.second.m_change;
@@ -2602,7 +2595,7 @@ void wallet2::rescan_spent()
COMMAND_RPC_IS_KEY_IMAGE_SPENT::response daemon_resp = AUTO_VAL_INIT(daemon_resp);
req.key_images = key_images;
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/is_key_image_spent", req, daemon_resp, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent");
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent");
@@ -2976,7 +2969,7 @@ void wallet2::commit_tx(pending_tx& ptx)
req.do_not_relay = false;
COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_json("/sendrawtransaction", req, daemon_send_resp, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "sendrawtransaction");
THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "sendrawtransaction");
@@ -2997,7 +2990,7 @@ void wallet2::commit_tx(pending_tx& ptx)
{
payment_id = get_payment_id(ptx);
dests = ptx.dests;
- BOOST_FOREACH(size_t idx, ptx.selected_transfers)
+ for(size_t idx: ptx.selected_transfers)
amount_in += m_transfers[idx].amount();
}
add_unconfirmed_tx(ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount);
@@ -3008,7 +3001,7 @@ void wallet2::commit_tx(pending_tx& ptx)
LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
- BOOST_FOREACH(size_t idx, ptx.selected_transfers)
+ for(size_t idx: ptx.selected_transfers)
{
set_spent(idx, 0);
}
@@ -3356,7 +3349,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
ptx_vector.push_back(ptx);
// mark transfers to be used as "spent"
- BOOST_FOREACH(size_t idx, ptx.selected_transfers)
+ for(size_t idx: ptx.selected_transfers)
{
set_spent(idx, 0);
}
@@ -3368,7 +3361,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
for (auto & ptx : ptx_vector)
{
// mark transfers to be used as not spent
- BOOST_FOREACH(size_t idx2, ptx.selected_transfers)
+ for(size_t idx2: ptx.selected_transfers)
{
set_unspent(idx2);
}
@@ -3387,7 +3380,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
for (auto & ptx : ptx_vector)
{
// mark transfers to be used as not spent
- BOOST_FOREACH(size_t idx2, ptx.selected_transfers)
+ for(size_t idx2: ptx.selected_transfers)
{
set_unspent(idx2);
}
@@ -3406,7 +3399,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
for (auto & ptx : ptx_vector)
{
// mark transfers to be used as not spent
- BOOST_FOREACH(size_t idx2, ptx.selected_transfers)
+ for(size_t idx2: ptx.selected_transfers)
{
set_unspent(idx2);
}
@@ -3437,7 +3430,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
req_t.params.amounts.resize(std::distance(req_t.params.amounts.begin(), end));
req_t.params.unlocked = true;
req_t.params.recent_cutoff = time(NULL) - RECENT_OUTPUT_ZONE;
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "transfer_selected");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
@@ -3564,7 +3557,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
// get the keys for those
m_daemon_rpc_mutex.lock();
- r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_outs.bin", req, daemon_resp, m_http_client, 200000);
+ r = epee::net_utils::invoke_http_bin("/get_outs.bin", req, daemon_resp, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_outs.bin");
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_outs.bin");
@@ -3667,7 +3660,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
// calculate total amount being sent to all destinations
// throw if total amount overflows uint64_t
- BOOST_FOREACH(auto& dt, dsts)
+ for(auto& dt: dsts)
{
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
needed_money += dt.amount;
@@ -3676,7 +3669,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
}
uint64_t found_money = 0;
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
found_money += m_transfers[idx].amount();
}
@@ -3692,7 +3685,7 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
typedef cryptonote::tx_source_entry::output_entry tx_output_entry;
size_t i = 0, out_index = 0;
std::vector<cryptonote::tx_source_entry> sources;
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
sources.resize(sources.size()+1);
cryptonote::tx_source_entry& src = sources.back();
@@ -3743,11 +3736,11 @@ void wallet2::transfer_selected(const std::vector<cryptonote::tx_destination_ent
std::vector<cryptonote::tx_destination_entry> splitted_dsts, dust_dsts;
uint64_t dust = 0;
destination_split_strategy(dsts, change_dts, dust_policy.dust_threshold, splitted_dsts, dust_dsts);
- BOOST_FOREACH(auto& d, dust_dsts) {
+ for(auto& d: dust_dsts) {
THROW_WALLET_EXCEPTION_IF(dust_policy.dust_threshold < d.amount, error::wallet_internal_error, "invalid dust value: dust = " +
std::to_string(d.amount) + ", dust_threshold = " + std::to_string(dust_policy.dust_threshold));
}
- BOOST_FOREACH(auto& d, dust_dsts) {
+ for(auto& d: dust_dsts) {
if (!dust_policy.add_to_fee)
splitted_dsts.push_back(cryptonote::tx_destination_entry(d.amount, dust_policy.addr_for_dust));
dust += d.amount;
@@ -3812,7 +3805,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
// calculate total amount being sent to all destinations
// throw if total amount overflows uint64_t
- BOOST_FOREACH(auto& dt, dsts)
+ for(auto& dt: dsts)
{
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
needed_money += dt.amount;
@@ -3821,7 +3814,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
}
uint64_t found_money = 0;
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
found_money += m_transfers[idx].amount();
}
@@ -3836,7 +3829,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("preparing outputs");
size_t i = 0, out_index = 0;
std::vector<cryptonote::tx_source_entry> sources;
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
sources.resize(sources.size()+1);
cryptonote::tx_source_entry& src = sources.back();
@@ -4107,7 +4100,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// calculate total amount being sent to all destinations
// throw if total amount overflows uint64_t
needed_money = 0;
- BOOST_FOREACH(auto& dt, dsts)
+ for(auto& dt: dsts)
{
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
needed_money += dt.amount;
@@ -4636,7 +4629,7 @@ std::vector<size_t> wallet2::select_available_outputs_from_histogram(uint64_t co
req_t.params.min_count = count;
req_t.params.max_count = 0;
req_t.params.unlocked = unlocked;
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "select_available_unmixable_outputs");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
@@ -4675,7 +4668,7 @@ uint64_t wallet2::get_num_rct_outputs()
req_t.params.amounts.push_back(0);
req_t.params.min_count = 0;
req_t.params.max_count = 0;
- bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool r = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_num_rct_outputs");
THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram");
@@ -4784,7 +4777,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_info";
- bool ok = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
+ bool ok = net_utils::invoke_http_json("/json_rpc", req_t, resp_t, m_http_client);
m_daemon_rpc_mutex.unlock();
if (ok)
{
@@ -5097,7 +5090,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag
}
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/is_key_image_spent", req, daemon_resp, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent");
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent");
@@ -5407,7 +5400,7 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
height_mid,
height_max
};
- bool r = net_utils::invoke_http_bin_remote_command2(get_daemon_address() + "/getblocks_by_height.bin", req, res, m_http_client);
+ bool r = net_utils::invoke_http_bin("/getblocks_by_height.bin", req, res, m_http_client);
if (!r || res.status != CORE_RPC_STATUS_OK)
{
std::ostringstream oss;
@@ -5424,9 +5417,9 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
throw std::runtime_error(oss.str());
}
cryptonote::block blk_min, blk_mid, blk_max;
- if (!parse_and_validate_block_from_blob(res.blocks[0].block, blk_min)) throw std::runtime_error("failed to parse blob at height " + height_min);
- if (!parse_and_validate_block_from_blob(res.blocks[1].block, blk_mid)) throw std::runtime_error("failed to parse blob at height " + height_mid);
- if (!parse_and_validate_block_from_blob(res.blocks[2].block, blk_max)) throw std::runtime_error("failed to parse blob at height " + height_max);
+ if (!parse_and_validate_block_from_blob(res.blocks[0].block, blk_min)) throw std::runtime_error("failed to parse blob at height " + std::to_string(height_min));
+ if (!parse_and_validate_block_from_blob(res.blocks[1].block, blk_mid)) throw std::runtime_error("failed to parse blob at height " + std::to_string(height_mid));
+ if (!parse_and_validate_block_from_blob(res.blocks[2].block, blk_max)) throw std::runtime_error("failed to parse blob at height " + std::to_string(height_max));
uint64_t timestamp_min = blk_min.timestamp;
uint64_t timestamp_mid = blk_mid.timestamp;
uint64_t timestamp_max = blk_max.timestamp;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 629011800..91d4db47e 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -61,8 +61,6 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "wallet.wallet2"
-#define WALLET_RCP_CONNECTION_TIMEOUT 200000
-
class Serialization_portability_wallet_Test;
namespace tools
@@ -96,6 +94,8 @@ namespace tools
{
friend class ::Serialization_portability_wallet_Test;
public:
+ static constexpr const std::chrono::seconds rpc_timeout = std::chrono::minutes(3) + std::chrono::seconds(30);
+
enum RefreshType {
RefreshFull,
RefreshOptimizeCoinbase,
@@ -107,7 +107,7 @@ namespace tools
wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers(true), m_print_ring_members(false), m_store_tx_info(true), m_default_mixin(0), m_default_priority(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0), m_confirm_missing_payment_id(true), m_node_rpc_proxy(m_http_client, m_daemon_rpc_mutex) {}
public:
- static const char* tr(const char* str);// { return i18n_translate(str, "cryptonote::simple_wallet"); }
+ static const char* tr(const char* str);
static bool has_testnet_option(const boost::program_options::variables_map& vm);
static void init_options(boost::program_options::options_description& desc_params);
@@ -342,8 +342,8 @@ namespace tools
// free block size. TODO: fix this so that it actually takes
// into account the current median block size rather than
// the minimum block size.
- void init(const std::string& daemon_address = "http://localhost:8080", uint64_t upper_transaction_size_limit = 0);
bool deinit();
+ bool init(std::string daemon_address = "http://localhost:8080", uint64_t upper_transaction_size_limit = 0);
void stop() { m_run.store(false, std::memory_order_relaxed); }
@@ -924,7 +924,7 @@ namespace tools
splitted_dsts.clear();
dust_dsts.clear();
- BOOST_FOREACH(auto& de, dsts)
+ for(auto& de: dsts)
{
cryptonote::decompose_amount_into_digits(de.amount, 0,
[&](uint64_t chunk) { splitted_dsts.push_back(cryptonote::tx_destination_entry(chunk, de.addr)); },
@@ -987,7 +987,7 @@ namespace tools
// calculate total amount being sent to all destinations
// throw if total amount overflows uint64_t
- BOOST_FOREACH(auto& dt, dsts)
+ for(auto& dt: dsts)
{
THROW_WALLET_EXCEPTION_IF(0 == dt.amount, error::zero_destination);
needed_money += dt.amount;
@@ -1008,7 +1008,7 @@ namespace tools
{
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
req.outs_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
const transfer_container::const_iterator it = m_transfers.begin() + idx;
THROW_WALLET_EXCEPTION_IF(it->m_tx.vout.size() <= it->m_internal_output_index, error::wallet_internal_error,
@@ -1018,7 +1018,7 @@ namespace tools
}
m_daemon_rpc_mutex.lock();
- bool r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000);
+ bool r = epee::net_utils::invoke_http_bin("/getrandom_outs.bin", req, daemon_resp, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getrandom_outs.bin");
THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getrandom_outs.bin");
@@ -1028,7 +1028,7 @@ namespace tools
std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(selected_transfers.size()));
std::unordered_map<uint64_t, uint64_t> scanty_outs;
- BOOST_FOREACH(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs, daemon_resp.outs)
+ for(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs: daemon_resp.outs)
{
if (amount_outs.outs.size() < fake_outputs_count)
{
@@ -1041,7 +1041,7 @@ namespace tools
//prepare inputs
size_t i = 0;
std::vector<cryptonote::tx_source_entry> sources;
- BOOST_FOREACH(size_t idx, selected_transfers)
+ for(size_t idx: selected_transfers)
{
sources.resize(sources.size()+1);
cryptonote::tx_source_entry& src = sources.back();
@@ -1052,7 +1052,7 @@ namespace tools
if(daemon_resp.outs.size())
{
daemon_resp.outs[i].outs.sort([](const out_entry& a, const out_entry& b){return a.global_amount_index < b.global_amount_index;});
- BOOST_FOREACH(out_entry& daemon_oe, daemon_resp.outs[i].outs)
+ for(out_entry& daemon_oe: daemon_resp.outs[i].outs)
{
if(td.m_global_output_index == daemon_oe.global_amount_index)
continue;
@@ -1094,11 +1094,11 @@ namespace tools
std::vector<cryptonote::tx_destination_entry> splitted_dsts, dust_dsts;
uint64_t dust = 0;
destination_split_strategy(dsts, change_dts, dust_policy.dust_threshold, splitted_dsts, dust_dsts);
- BOOST_FOREACH(auto& d, dust_dsts) {
+ for(auto& d: dust_dsts) {
THROW_WALLET_EXCEPTION_IF(dust_policy.dust_threshold < d.amount, error::wallet_internal_error, "invalid dust value: dust = " +
std::to_string(d.amount) + ", dust_threshold = " + std::to_string(dust_policy.dust_threshold));
}
- BOOST_FOREACH(auto& d, dust_dsts) {
+ for(auto& d: dust_dsts) {
if (!dust_policy.add_to_fee)
splitted_dsts.push_back(cryptonote::tx_destination_entry(d.amount, dust_policy.addr_for_dust));
dust += d.amount;
diff --git a/src/wallet/wallet2_api.h b/src/wallet/wallet2_api.h
index 6cabcd849..563f16eaa 100644
--- a/src/wallet/wallet2_api.h
+++ b/src/wallet/wallet2_api.h
@@ -435,6 +435,7 @@ struct Wallet
static std::string genPaymentId();
static bool paymentIdValid(const std::string &paiment_id);
static bool addressValid(const std::string &str, bool testnet);
+ static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error);
static std::string paymentIdFromAddress(const std::string &str, bool testnet);
static uint64_t maximumAllowedAmount();
@@ -614,6 +615,25 @@ struct WalletManager
*/
virtual Wallet * recoveryWallet(const std::string &path, const std::string &memo, bool testnet = false, uint64_t restoreHeight = 0) = 0;
+ /*!
+ * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted
+ * \param path Name of wallet file to be created
+ * \param language language
+ * \param testnet testnet
+ * \param restoreHeight restore from start height
+ * \param addressString public address
+ * \param viewKeyString view key
+ * \param spendKeyString spend key (optional)
+ * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
+ */
+ virtual Wallet * createWalletFromKeys(const std::string &path,
+ const std::string &language,
+ bool testnet,
+ uint64_t restoreHeight,
+ const std::string &addressString,
+ const std::string &viewKeyString,
+ const std::string &spendKeyString = "") = 0;
+
/*!
* \brief Closes wallet. In case operation succeded, wallet object deleted. in case operation failed, wallet object not deleted
* \param wallet previously opened / created wallet instance
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 6ecc29b6d..dcf8f8e6d 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -369,7 +369,7 @@ namespace tools
cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, long_payment_id);
}
/* or short payment ID */
- else if (!wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) {
+ else if (wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) {
cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, short_payment_id);
}
else {
diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp
index 557e3f07c..5851d9c6a 100644
--- a/tests/core_tests/chaingen_main.cpp
+++ b/tests/core_tests/chaingen_main.cpp
@@ -51,7 +51,7 @@ int main(int argc, char* argv[])
//set up logging options
mlog_configure(mlog_get_default_log_path("core_tests.log"), true);
- mlog_set_log_level(3);
+ mlog_set_log_level(2);
po::options_description desc_options("Allowed options");
command_line::add_arg(desc_options, command_line::arg_help);
diff --git a/tests/functional_tests/transactions_flow_test.cpp b/tests/functional_tests/transactions_flow_test.cpp
index 73c79c237..5666f49bf 100644
--- a/tests/functional_tests/transactions_flow_test.cpp
+++ b/tests/functional_tests/transactions_flow_test.cpp
@@ -159,14 +159,14 @@ bool transactions_flow_test(std::string& working_folder,
epee::net_utils::http::http_simple_client http_client;
COMMAND_RPC_STOP_MINING::request daemon1_req = AUTO_VAL_INIT(daemon1_req);
COMMAND_RPC_STOP_MINING::response daemon1_rsp = AUTO_VAL_INIT(daemon1_rsp);
- bool r = net_utils::invoke_http_json_remote_command2(daemon_addr_a + "/stop_mine", daemon1_req, daemon1_rsp, http_client, 10000);
+ bool r = http_client.set_server(daemon_addr_a) && net_utils::invoke_http_json("/stop_mine", daemon1_req, daemon1_rsp, http_client, std::chrono::seconds(10));
CHECK_AND_ASSERT_MES(r, false, "failed to stop mining");
COMMAND_RPC_START_MINING::request daemon_req = AUTO_VAL_INIT(daemon_req);
COMMAND_RPC_START_MINING::response daemon_rsp = AUTO_VAL_INIT(daemon_rsp);
daemon_req.miner_address = w1.get_account().get_public_address_str(false);
daemon_req.threads_count = 9;
- r = net_utils::invoke_http_json_remote_command2(daemon_addr_a + "/start_mining", daemon_req, daemon_rsp, http_client, 10000);
+ r = net_utils::invoke_http_json("/start_mining", daemon_req, daemon_rsp, http_client, std::chrono::seconds(10));
CHECK_AND_ASSERT_MES(r, false, "failed to get getrandom_outs");
CHECK_AND_ASSERT_MES(daemon_rsp.status == CORE_RPC_STATUS_OK, false, "failed to getrandom_outs.bin");