mirror of
https://github.com/wownero/wownero.git
synced 2026-10-26 02:48:33 +01:00
daemon: remove bootstrap mode
This commit is contained in:
@@ -986,71 +986,6 @@ bool t_command_parser_executor::check_blockchain_pruning(const std::vector<std::
|
|||||||
return m_executor.check_blockchain_pruning();
|
return m_executor.check_blockchain_pruning();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool t_command_parser_executor::set_bootstrap_daemon(const std::vector<std::string>& args)
|
|
||||||
{
|
|
||||||
struct parsed_t
|
|
||||||
{
|
|
||||||
std::string address;
|
|
||||||
std::string user;
|
|
||||||
std::string password;
|
|
||||||
std::string proxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
boost::optional<parsed_t> parsed = [&args]() -> boost::optional<parsed_t> {
|
|
||||||
const size_t args_count = args.size();
|
|
||||||
if (args_count == 0)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (args[0] == "auto")
|
|
||||||
{
|
|
||||||
if (args_count == 1)
|
|
||||||
{
|
|
||||||
return {{args[0], "", "", ""}};
|
|
||||||
}
|
|
||||||
if (args_count == 2)
|
|
||||||
{
|
|
||||||
return {{args[0], "", "", args[1]}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (args[0] == "none")
|
|
||||||
{
|
|
||||||
if (args_count == 1)
|
|
||||||
{
|
|
||||||
return {{"", "", "", ""}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (args_count == 1)
|
|
||||||
{
|
|
||||||
return {{args[0], "", "", ""}};
|
|
||||||
}
|
|
||||||
if (args_count == 2)
|
|
||||||
{
|
|
||||||
return {{args[0], "", "", args[1]}};
|
|
||||||
}
|
|
||||||
if (args_count == 3)
|
|
||||||
{
|
|
||||||
return {{args[0], args[1], args[2], ""}};
|
|
||||||
}
|
|
||||||
if (args_count == 4)
|
|
||||||
{
|
|
||||||
return {{args[0], args[1], args[2], args[3]}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (!parsed)
|
|
||||||
{
|
|
||||||
std::cout << "Invalid syntax: Wrong number of parameters. For more details, use the help command." << std::endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_executor.set_bootstrap_daemon(parsed->address, parsed->user, parsed->password, parsed->proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool t_command_parser_executor::flush_cache(const std::vector<std::string>& args)
|
bool t_command_parser_executor::flush_cache(const std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
bool bad_blocks = false;
|
bool bad_blocks = false;
|
||||||
|
|||||||
@@ -150,8 +150,6 @@ public:
|
|||||||
|
|
||||||
bool print_net_stats(const std::vector<std::string>& args);
|
bool print_net_stats(const std::vector<std::string>& args);
|
||||||
|
|
||||||
bool set_bootstrap_daemon(const std::vector<std::string>& args);
|
|
||||||
|
|
||||||
bool flush_cache(const std::vector<std::string>& args);
|
bool flush_cache(const std::vector<std::string>& args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -318,13 +318,6 @@ t_command_server::t_command_server(
|
|||||||
, std::bind(&t_command_parser_executor::check_blockchain_pruning, &m_parser, p::_1)
|
, std::bind(&t_command_parser_executor::check_blockchain_pruning, &m_parser, p::_1)
|
||||||
, "Check the blockchain pruning."
|
, "Check the blockchain pruning."
|
||||||
);
|
);
|
||||||
m_command_lookup.set_handler(
|
|
||||||
"set_bootstrap_daemon"
|
|
||||||
, std::bind(&t_command_parser_executor::set_bootstrap_daemon, &m_parser, p::_1)
|
|
||||||
, "set_bootstrap_daemon (auto | none | host[:port] [username] [password]) [proxy_ip:proxy_port]"
|
|
||||||
, "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n"
|
|
||||||
"Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
|
|
||||||
);
|
|
||||||
m_command_lookup.set_handler(
|
m_command_lookup.set_handler(
|
||||||
"flush_cache"
|
"flush_cache"
|
||||||
, std::bind(&t_command_parser_executor::flush_cache, &m_parser, p::_1)
|
, std::bind(&t_command_parser_executor::flush_cache, &m_parser, p::_1)
|
||||||
|
|||||||
@@ -436,10 +436,6 @@ static float get_sync_percentage(uint64_t height, uint64_t target_height)
|
|||||||
return 99.9f; // to avoid 100% when not fully synced
|
return 99.9f; // to avoid 100% when not fully synced
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
static float get_sync_percentage(const cryptonote::COMMAND_RPC_GET_INFO::response &ires)
|
|
||||||
{
|
|
||||||
return get_sync_percentage(ires.height, ires.target_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool t_rpc_command_executor::show_status() {
|
bool t_rpc_command_executor::show_status() {
|
||||||
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
|
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
|
||||||
@@ -499,27 +495,13 @@ bool t_rpc_command_executor::show_status() {
|
|||||||
|
|
||||||
std::time_t uptime = std::time(nullptr) - ires.start_time;
|
std::time_t uptime = std::time(nullptr) - ires.start_time;
|
||||||
uint64_t net_height = ires.target_height > ires.height ? ires.target_height : ires.height;
|
uint64_t net_height = ires.target_height > ires.height ? ires.target_height : ires.height;
|
||||||
std::string bootstrap_msg;
|
|
||||||
if (ires.was_bootstrap_ever_used)
|
|
||||||
{
|
|
||||||
bootstrap_msg = ", bootstrapping from " + ires.bootstrap_daemon_address;
|
|
||||||
if (ires.untrusted)
|
|
||||||
{
|
|
||||||
bootstrap_msg += (boost::format(", local height: %llu (%.1f%%)") % ires.height_without_bootstrap % get_sync_percentage(ires.height_without_bootstrap, net_height)).str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bootstrap_msg += " was used before";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << boost::format("Height: %llu/%llu (%.1f%%) on %s%s, %s, net hash %s, v%u%s, %u(out)+%u(in) connections")
|
str << boost::format("Height: %llu/%llu (%.1f%%) on %s, %s, net hash %s, v%u%s, %u(out)+%u(in) connections")
|
||||||
% (unsigned long long)ires.height
|
% (unsigned long long)ires.height
|
||||||
% (unsigned long long)net_height
|
% (unsigned long long)net_height
|
||||||
% get_sync_percentage(ires)
|
% get_sync_percentage(ires.height, ires.target_height)
|
||||||
% (ires.testnet ? "testnet" : ires.stagenet ? "stagenet" : "mainnet")
|
% (ires.testnet ? "testnet" : ires.stagenet ? "stagenet" : "mainnet")
|
||||||
% bootstrap_msg
|
|
||||||
% (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed)) : "not mining")
|
% (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed)) : "not mining")
|
||||||
% get_mining_speed(cryptonote::difficulty_type(ires.wide_difficulty) / ires.target)
|
% get_mining_speed(cryptonote::difficulty_type(ires.wide_difficulty) / ires.target)
|
||||||
% (unsigned)hfres.version
|
% (unsigned)hfres.version
|
||||||
@@ -2402,44 +2384,6 @@ bool t_rpc_command_executor::check_blockchain_pruning()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool t_rpc_command_executor::set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const std::string &username,
|
|
||||||
const std::string &password,
|
|
||||||
const std::string &proxy)
|
|
||||||
{
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request req;
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response res;
|
|
||||||
const std::string fail_message = "Unsuccessful";
|
|
||||||
|
|
||||||
req.address = address;
|
|
||||||
req.username = username;
|
|
||||||
req.password = password;
|
|
||||||
req.proxy = proxy;
|
|
||||||
|
|
||||||
if (m_is_rpc)
|
|
||||||
{
|
|
||||||
if (!m_rpc_client->rpc_request(req, res, "/set_bootstrap_daemon", fail_message))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!m_rpc_server->on_set_bootstrap_daemon(req, res) || res.status != CORE_RPC_STATUS_OK)
|
|
||||||
{
|
|
||||||
tools::fail_msg_writer() << make_error(fail_message, res.status);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tools::success_msg_writer()
|
|
||||||
<< "Successfully set bootstrap daemon address to "
|
|
||||||
<< (!req.address.empty() ? req.address : "none");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool t_rpc_command_executor::flush_cache(bool bad_blocks)
|
bool t_rpc_command_executor::flush_cache(bool bad_blocks)
|
||||||
{
|
{
|
||||||
cryptonote::COMMAND_RPC_FLUSH_CACHE::request req;
|
cryptonote::COMMAND_RPC_FLUSH_CACHE::request req;
|
||||||
|
|||||||
@@ -164,12 +164,6 @@ public:
|
|||||||
|
|
||||||
bool version();
|
bool version();
|
||||||
|
|
||||||
bool set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const std::string &username,
|
|
||||||
const std::string &password,
|
|
||||||
const std::string &proxy);
|
|
||||||
|
|
||||||
bool flush_cache(bool invalid_blocks);
|
bool flush_cache(bool invalid_blocks);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ set(rpc_base_sources
|
|||||||
rpc_handler.cpp)
|
rpc_handler.cpp)
|
||||||
|
|
||||||
set(rpc_sources
|
set(rpc_sources
|
||||||
bootstrap_daemon.cpp
|
|
||||||
bootstrap_node_selector.cpp
|
|
||||||
core_rpc_server.cpp
|
core_rpc_server.cpp
|
||||||
rpc_version_str.cpp
|
rpc_version_str.cpp
|
||||||
instanciations.cpp)
|
instanciations.cpp)
|
||||||
@@ -63,7 +61,6 @@ set(rpc_pub_headers zmq_pub.h)
|
|||||||
set(daemon_rpc_server_headers)
|
set(daemon_rpc_server_headers)
|
||||||
|
|
||||||
set(rpc_private_headers
|
set(rpc_private_headers
|
||||||
bootstrap_daemon.h
|
|
||||||
core_rpc_server.h
|
core_rpc_server.h
|
||||||
core_rpc_server_commands_defs.h
|
core_rpc_server_commands_defs.h
|
||||||
core_rpc_server_error_codes.h)
|
core_rpc_server_error_codes.h)
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
#include "bootstrap_daemon.h"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <boost/thread/locks.hpp>
|
|
||||||
|
|
||||||
#include "crypto/crypto.h"
|
|
||||||
#include "cryptonote_core/cryptonote_core.h"
|
|
||||||
#include "misc_log_ex.h"
|
|
||||||
#include "net/parse.h"
|
|
||||||
|
|
||||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
|
||||||
#define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc.bootstrap_daemon"
|
|
||||||
|
|
||||||
namespace cryptonote
|
|
||||||
{
|
|
||||||
|
|
||||||
bootstrap_daemon::bootstrap_daemon(
|
|
||||||
std::function<std::map<std::string, bool>()> get_public_nodes,
|
|
||||||
const std::string &proxy)
|
|
||||||
: m_selector(new bootstrap_node::selector_auto(std::move(get_public_nodes)))
|
|
||||||
{
|
|
||||||
set_proxy(proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap_daemon::bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
boost::optional<epee::net_utils::http::login> credentials,
|
|
||||||
const std::string &proxy)
|
|
||||||
: m_selector(nullptr)
|
|
||||||
{
|
|
||||||
set_proxy(proxy);
|
|
||||||
if (!set_server(address, std::move(credentials)))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("invalid bootstrap daemon address or credentials");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string bootstrap_daemon::address() const noexcept
|
|
||||||
{
|
|
||||||
const auto& host = m_http_client.get_host();
|
|
||||||
if (host.empty())
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
return host + ":" + m_http_client.get_port();
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<uint64_t, uint64_t>> bootstrap_daemon::get_height()
|
|
||||||
{
|
|
||||||
cryptonote::COMMAND_RPC_GET_INFO::request req;
|
|
||||||
cryptonote::COMMAND_RPC_GET_INFO::response res;
|
|
||||||
|
|
||||||
if (!invoke_http_json("/getinfo", req, res))
|
|
||||||
{
|
|
||||||
return boost::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status != CORE_RPC_STATUS_OK)
|
|
||||||
{
|
|
||||||
return boost::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {{res.height, res.target_height}};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bootstrap_daemon::handle_result(bool success, const std::string &status)
|
|
||||||
{
|
|
||||||
const bool failed = !success || (status == CORE_RPC_STATUS_PAYMENT_REQUIRED);
|
|
||||||
if (failed && m_selector)
|
|
||||||
{
|
|
||||||
const std::string current_address = address();
|
|
||||||
m_http_client.disconnect();
|
|
||||||
|
|
||||||
const boost::unique_lock<boost::mutex> lock(m_selector_mutex);
|
|
||||||
m_selector->handle_result(current_address, !failed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bootstrap_daemon::set_proxy(const std::string &address)
|
|
||||||
{
|
|
||||||
if (!address.empty() && !net::get_tcp_endpoint(address))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("invalid proxy address format");
|
|
||||||
}
|
|
||||||
if (!m_http_client.set_proxy(address))
|
|
||||||
{
|
|
||||||
throw std::runtime_error("failed to set proxy address");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bootstrap_daemon::set_server(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials /* = boost::none */)
|
|
||||||
{
|
|
||||||
if (!m_http_client.set_server(address, credentials))
|
|
||||||
{
|
|
||||||
MERROR("Failed to set bootstrap daemon address " << address);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MINFO("Changed bootstrap daemon address to " << address);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool bootstrap_daemon::switch_server_if_needed()
|
|
||||||
{
|
|
||||||
if (m_http_client.is_connected() || !m_selector)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<bootstrap_node::node_info> node;
|
|
||||||
{
|
|
||||||
const boost::unique_lock<boost::mutex> lock(m_selector_mutex);
|
|
||||||
node = m_selector->next_node();
|
|
||||||
}
|
|
||||||
if (node) {
|
|
||||||
return set_server(node->address, node->credentials);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <boost/optional/optional.hpp>
|
|
||||||
#include <boost/thread/mutex.hpp>
|
|
||||||
#include <boost/utility/string_ref.hpp>
|
|
||||||
|
|
||||||
#include "net/http.h"
|
|
||||||
#include "storages/http_abstract_invoke.h"
|
|
||||||
|
|
||||||
#include "bootstrap_node_selector.h"
|
|
||||||
|
|
||||||
namespace cryptonote
|
|
||||||
{
|
|
||||||
|
|
||||||
class bootstrap_daemon
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bootstrap_daemon(
|
|
||||||
std::function<std::map<std::string, bool>()> get_public_nodes,
|
|
||||||
const std::string &proxy);
|
|
||||||
bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
boost::optional<epee::net_utils::http::login> credentials,
|
|
||||||
const std::string &proxy);
|
|
||||||
|
|
||||||
std::string address() const noexcept;
|
|
||||||
boost::optional<std::pair<uint64_t, uint64_t>> get_height();
|
|
||||||
bool handle_result(bool success, const std::string &status);
|
|
||||||
|
|
||||||
template <class t_request, class t_response>
|
|
||||||
bool invoke_http_json(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct)
|
|
||||||
{
|
|
||||||
if (!switch_server_if_needed())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool result = epee::net_utils::invoke_http_json(uri, out_struct, result_struct, m_http_client);
|
|
||||||
return handle_result(result, result_struct.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class t_request, class t_response>
|
|
||||||
bool invoke_http_bin(const boost::string_ref uri, const t_request &out_struct, t_response &result_struct)
|
|
||||||
{
|
|
||||||
if (!switch_server_if_needed())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool result = epee::net_utils::invoke_http_bin(uri, out_struct, result_struct, m_http_client);
|
|
||||||
return handle_result(result, result_struct.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class t_request, class t_response>
|
|
||||||
bool invoke_http_json_rpc(const boost::string_ref command_name, const t_request &out_struct, t_response &result_struct)
|
|
||||||
{
|
|
||||||
if (!switch_server_if_needed())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool result = epee::net_utils::invoke_http_json_rpc(
|
|
||||||
"/json_rpc",
|
|
||||||
std::string(command_name.begin(), command_name.end()),
|
|
||||||
out_struct,
|
|
||||||
result_struct,
|
|
||||||
m_http_client);
|
|
||||||
return handle_result(result, result_struct.status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_proxy(const std::string &address);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool set_server(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials = boost::none);
|
|
||||||
bool switch_server_if_needed();
|
|
||||||
|
|
||||||
private:
|
|
||||||
net::http::client m_http_client;
|
|
||||||
const std::unique_ptr<bootstrap_node::selector> m_selector;
|
|
||||||
boost::mutex m_selector_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
// Copyright (c) 2020-2024, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. 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.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder 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 HOLDER OR CONTRIBUTORS 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.
|
|
||||||
|
|
||||||
#include "bootstrap_node_selector.h"
|
|
||||||
|
|
||||||
#include "crypto/crypto.h"
|
|
||||||
|
|
||||||
namespace cryptonote
|
|
||||||
{
|
|
||||||
namespace bootstrap_node
|
|
||||||
{
|
|
||||||
|
|
||||||
void selector_auto::node::handle_result(bool success)
|
|
||||||
{
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
fails = std::min(std::numeric_limits<size_t>::max() - 2, fails) + 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fails = std::max(std::numeric_limits<size_t>::min() + 2, fails) - 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void selector_auto::handle_result(const std::string &address, bool success)
|
|
||||||
{
|
|
||||||
auto &nodes_by_address = m_nodes.get<by_address>();
|
|
||||||
const auto it = nodes_by_address.find(address);
|
|
||||||
if (it != nodes_by_address.end())
|
|
||||||
{
|
|
||||||
nodes_by_address.modify(it, [success](node &entry) {
|
|
||||||
entry.handle_result(success);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<node_info> selector_auto::next_node()
|
|
||||||
{
|
|
||||||
if (!has_at_least_one_good_node())
|
|
||||||
{
|
|
||||||
append_new_nodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_nodes.empty())
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto node = m_nodes.get<by_fails>().begin();
|
|
||||||
const size_t count = std::distance(node, m_nodes.get<by_fails>().upper_bound(node->fails));
|
|
||||||
std::advance(node, crypto::rand_idx(count));
|
|
||||||
|
|
||||||
return {{node->address, {}}};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool selector_auto::has_at_least_one_good_node() const
|
|
||||||
{
|
|
||||||
return !m_nodes.empty() && m_nodes.get<by_fails>().begin()->fails == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void selector_auto::append_new_nodes()
|
|
||||||
{
|
|
||||||
bool updated = false;
|
|
||||||
|
|
||||||
for (const auto &node : m_get_nodes())
|
|
||||||
{
|
|
||||||
const auto &address = node.first;
|
|
||||||
const auto &white = node.second;
|
|
||||||
const size_t initial_score = white ? 0 : 1;
|
|
||||||
updated |= m_nodes.get<by_address>().insert({address, initial_score}).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updated)
|
|
||||||
{
|
|
||||||
truncate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void selector_auto::truncate()
|
|
||||||
{
|
|
||||||
const size_t total = m_nodes.size();
|
|
||||||
if (total > m_max_nodes)
|
|
||||||
{
|
|
||||||
auto &nodes_by_fails = m_nodes.get<by_fails>();
|
|
||||||
auto from = nodes_by_fails.rbegin();
|
|
||||||
std::advance(from, total - m_max_nodes);
|
|
||||||
nodes_by_fails.erase(from.base(), nodes_by_fails.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
// Copyright (c) 2020-2024, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. 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.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder 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 HOLDER OR CONTRIBUTORS 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 <functional>
|
|
||||||
#include <limits>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <boost/multi_index_container.hpp>
|
|
||||||
#include <boost/multi_index/member.hpp>
|
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
|
||||||
#include <boost/optional/optional.hpp>
|
|
||||||
|
|
||||||
#include "net/http_client.h"
|
|
||||||
|
|
||||||
namespace cryptonote
|
|
||||||
{
|
|
||||||
namespace bootstrap_node
|
|
||||||
{
|
|
||||||
|
|
||||||
struct node_info
|
|
||||||
{
|
|
||||||
std::string address;
|
|
||||||
boost::optional<epee::net_utils::http::login> credentials;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct selector
|
|
||||||
{
|
|
||||||
virtual ~selector() = default;
|
|
||||||
|
|
||||||
virtual void handle_result(const std::string &address, bool success) = 0;
|
|
||||||
virtual boost::optional<node_info> next_node() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class selector_auto : public selector
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
selector_auto(std::function<std::map<std::string, bool>()> get_nodes, size_t max_nodes = 1000)
|
|
||||||
: m_get_nodes(std::move(get_nodes))
|
|
||||||
, m_max_nodes(max_nodes)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void handle_result(const std::string &address, bool success) final;
|
|
||||||
boost::optional<node_info> next_node() final;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool has_at_least_one_good_node() const;
|
|
||||||
void append_new_nodes();
|
|
||||||
void truncate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct node
|
|
||||||
{
|
|
||||||
std::string address;
|
|
||||||
size_t fails;
|
|
||||||
|
|
||||||
void handle_result(bool success);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct by_address {};
|
|
||||||
struct by_fails {};
|
|
||||||
|
|
||||||
typedef boost::multi_index_container<
|
|
||||||
node,
|
|
||||||
boost::multi_index::indexed_by<
|
|
||||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_address>, boost::multi_index::member<node, std::string, &node::address>>,
|
|
||||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_fails>, boost::multi_index::member<node, size_t, &node::fails>>
|
|
||||||
>
|
|
||||||
> nodes_list;
|
|
||||||
|
|
||||||
const std::function<std::map<std::string, bool>()> m_get_nodes;
|
|
||||||
const size_t m_max_nodes;
|
|
||||||
nodes_list m_nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+45
-438
@@ -153,9 +153,6 @@ namespace cryptonote
|
|||||||
command_line::add_arg(desc, arg_rpc_bind_port);
|
command_line::add_arg(desc, arg_rpc_bind_port);
|
||||||
command_line::add_arg(desc, arg_rpc_restricted_bind_port);
|
command_line::add_arg(desc, arg_rpc_restricted_bind_port);
|
||||||
command_line::add_arg(desc, arg_restricted_rpc);
|
command_line::add_arg(desc, arg_restricted_rpc);
|
||||||
command_line::add_arg(desc, arg_bootstrap_daemon_address);
|
|
||||||
command_line::add_arg(desc, arg_bootstrap_daemon_login);
|
|
||||||
command_line::add_arg(desc, arg_bootstrap_daemon_proxy);
|
|
||||||
cryptonote::rpc_args::init_options(desc, true);
|
cryptonote::rpc_args::init_options(desc, true);
|
||||||
command_line::add_arg(desc, arg_rpc_max_connections_per_public_ip);
|
command_line::add_arg(desc, arg_rpc_max_connections_per_public_ip);
|
||||||
command_line::add_arg(desc, arg_rpc_max_connections_per_private_ip);
|
command_line::add_arg(desc, arg_rpc_max_connections_per_private_ip);
|
||||||
@@ -169,79 +166,9 @@ namespace cryptonote
|
|||||||
)
|
)
|
||||||
: m_core(cr)
|
: m_core(cr)
|
||||||
, m_p2p(p2p)
|
, m_p2p(p2p)
|
||||||
, m_was_bootstrap_ever_used(false)
|
|
||||||
, disable_rpc_ban(false)
|
, disable_rpc_ban(false)
|
||||||
{}
|
{}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool core_rpc_server::set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const std::string &username_password,
|
|
||||||
const std::string &proxy)
|
|
||||||
{
|
|
||||||
boost::optional<epee::net_utils::http::login> credentials;
|
|
||||||
const auto loc = username_password.find(':');
|
|
||||||
if (loc != std::string::npos)
|
|
||||||
{
|
|
||||||
credentials = epee::net_utils::http::login(username_password.substr(0, loc), username_password.substr(loc + 1));
|
|
||||||
}
|
|
||||||
return set_bootstrap_daemon(address, credentials, proxy);
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
std::map<std::string, bool> core_rpc_server::get_public_nodes(uint32_t/* = 0*/)
|
|
||||||
{
|
|
||||||
COMMAND_RPC_GET_PUBLIC_NODES::request request;
|
|
||||||
COMMAND_RPC_GET_PUBLIC_NODES::response response;
|
|
||||||
|
|
||||||
request.gray = true;
|
|
||||||
request.white = true;
|
|
||||||
request.include_blocked = false;
|
|
||||||
if (!on_get_public_nodes(request, response) || response.status != CORE_RPC_STATUS_OK)
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, bool> result;
|
|
||||||
|
|
||||||
const auto append = [&result](const std::vector<public_node> &nodes, bool white) {
|
|
||||||
for (const auto &node : nodes)
|
|
||||||
{
|
|
||||||
result.insert(std::make_pair(node.host + ":" + std::to_string(node.rpc_port), white));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
append(response.white, true);
|
|
||||||
append(response.gray, false);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
bool core_rpc_server::set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const boost::optional<epee::net_utils::http::login> &credentials,
|
|
||||||
const std::string &proxy)
|
|
||||||
{
|
|
||||||
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
|
|
||||||
if (address.empty())
|
|
||||||
{
|
|
||||||
m_bootstrap_daemon.reset(nullptr);
|
|
||||||
}
|
|
||||||
else if (address == "auto")
|
|
||||||
{
|
|
||||||
auto get_nodes = [this]() {
|
|
||||||
return get_public_nodes(0);
|
|
||||||
};
|
|
||||||
m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_should_use_bootstrap_daemon = m_bootstrap_daemon.get() != nullptr;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
core_rpc_server::~core_rpc_server()
|
core_rpc_server::~core_rpc_server()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -253,7 +180,6 @@ namespace cryptonote
|
|||||||
, const std::string& proxy
|
, const std::string& proxy
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_bootstrap_daemon_proxy = proxy;
|
|
||||||
m_restricted = restricted;
|
m_restricted = restricted;
|
||||||
m_net_server.set_threads_prefix("RPC");
|
m_net_server.set_threads_prefix("RPC");
|
||||||
m_net_server.set_connection_filter(&m_p2p);
|
m_net_server.set_connection_filter(&m_p2p);
|
||||||
@@ -277,15 +203,6 @@ namespace cryptonote
|
|||||||
disable_rpc_ban = rpc_config->disable_rpc_ban;
|
disable_rpc_ban = rpc_config->disable_rpc_ban;
|
||||||
const std::string data_dir{command_line::get_arg(vm, cryptonote::arg_data_dir)};
|
const std::string data_dir{command_line::get_arg(vm, cryptonote::arg_data_dir)};
|
||||||
|
|
||||||
if (!set_bootstrap_daemon(
|
|
||||||
command_line::get_arg(vm, arg_bootstrap_daemon_address),
|
|
||||||
command_line::get_arg(vm, arg_bootstrap_daemon_login),
|
|
||||||
command_line::get_arg(vm, arg_bootstrap_daemon_proxy)))
|
|
||||||
{
|
|
||||||
MFATAL("Failed to parse bootstrap daemon address");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<epee::net_utils::http::login> http_login{};
|
boost::optional<epee::net_utils::http::login> http_login{};
|
||||||
|
|
||||||
if (rpc_config->login)
|
if (rpc_config->login)
|
||||||
@@ -408,9 +325,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_height);
|
RPC_TRACKER(get_height);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_HEIGHT>(invoke_http_mode::JON, "/getheight", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
crypto::hash hash;
|
crypto::hash hash;
|
||||||
m_core.get_blockchain_top(res.height, hash);
|
m_core.get_blockchain_top(res.height, hash);
|
||||||
@@ -423,22 +337,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_info);
|
RPC_TRACKER(get_info);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_INFO>(invoke_http_mode::JON, "/getinfo", req, res, r))
|
|
||||||
{
|
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_bootstrap_daemon.get() != nullptr)
|
|
||||||
{
|
|
||||||
res.bootstrap_daemon_address = m_bootstrap_daemon->address();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
crypto::hash top_hash;
|
|
||||||
m_core.get_blockchain_top(res.height_without_bootstrap, top_hash);
|
|
||||||
++res.height_without_bootstrap; // turn top block height into blockchain height
|
|
||||||
res.was_bootstrap_ever_used = true;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
|
|
||||||
@@ -473,21 +371,6 @@ namespace cryptonote
|
|||||||
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
|
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
|
||||||
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
||||||
res.offline = m_core.offline();
|
res.offline = m_core.offline();
|
||||||
res.height_without_bootstrap = restricted ? 0 : res.height;
|
|
||||||
if (restricted)
|
|
||||||
{
|
|
||||||
res.bootstrap_daemon_address = "";
|
|
||||||
res.was_bootstrap_ever_used = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_bootstrap_daemon.get() != nullptr)
|
|
||||||
{
|
|
||||||
res.bootstrap_daemon_address = m_bootstrap_daemon->address();
|
|
||||||
}
|
|
||||||
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
|
||||||
}
|
|
||||||
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
|
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
|
||||||
if (restricted)
|
if (restricted)
|
||||||
res.database_size = round_up(res.database_size, 5ull* 1024 * 1024 * 1024);
|
res.database_size = round_up(res.database_size, 5ull* 1024 * 1024 * 1024);
|
||||||
@@ -504,7 +387,7 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_net_stats(const COMMAND_RPC_GET_NET_STATS::request& req, COMMAND_RPC_GET_NET_STATS::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_net_stats(const COMMAND_RPC_GET_NET_STATS::request& req, COMMAND_RPC_GET_NET_STATS::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_net_stats);
|
RPC_TRACKER(get_net_stats);
|
||||||
// No bootstrap daemon check: Only ever get stats about local server
|
|
||||||
res.start_time = (uint64_t)m_core.get_start_time();
|
res.start_time = (uint64_t)m_core.get_start_time();
|
||||||
{
|
{
|
||||||
CRITICAL_REGION_LOCAL(epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in);
|
CRITICAL_REGION_LOCAL(epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in);
|
||||||
@@ -532,17 +415,6 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
RPC_TRACKER(get_blocks);
|
RPC_TRACKER(get_blocks);
|
||||||
|
|
||||||
bool use_bootstrap_daemon;
|
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
use_bootstrap_daemon = m_should_use_bootstrap_daemon;
|
|
||||||
}
|
|
||||||
if (use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
bool r;
|
|
||||||
return use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_FAST>(invoke_http_mode::BIN, "/getblocks.bin", req, res, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
res.daemon_time = (uint64_t)time(NULL);
|
res.daemon_time = (uint64_t)time(NULL);
|
||||||
// Always set daemon time, and set it early rather than late, as delivering some incremental pool
|
// Always set daemon time, and set it early rather than late, as delivering some incremental pool
|
||||||
// info twice because of slightly overlapping time intervals is no problem, whereas producing gaps
|
// info twice because of slightly overlapping time intervals is no problem, whereas producing gaps
|
||||||
@@ -713,9 +585,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_alt_blocks_hashes(const COMMAND_RPC_GET_ALT_BLOCKS_HASHES::request& req, COMMAND_RPC_GET_ALT_BLOCKS_HASHES::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_alt_blocks_hashes);
|
RPC_TRACKER(get_alt_blocks_hashes);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_ALT_BLOCKS_HASHES>(invoke_http_mode::JON, "/get_alt_blocks_hashes", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
std::vector<block> blks;
|
std::vector<block> blks;
|
||||||
|
|
||||||
@@ -740,9 +609,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_blocks_by_height(const COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCKS_BY_HEIGHT::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_blocks_by_height);
|
RPC_TRACKER(get_blocks_by_height);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
||||||
@@ -781,9 +647,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_hashes);
|
RPC_TRACKER(get_hashes);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_HASHES_FAST>(invoke_http_mode::BIN, "/gethashes.bin", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res.start_height = req.start_height;
|
res.start_height = req.start_height;
|
||||||
if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, res.m_block_ids, NULL, res.start_height, res.current_height, false))
|
if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, res.m_block_ids, NULL, res.start_height, res.current_height, false))
|
||||||
@@ -800,9 +663,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_outs_bin(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_outs_bin);
|
RPC_TRACKER(get_outs_bin);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUTS_BIN>(invoke_http_mode::BIN, "/get_outs.bin", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res.status = "Failed";
|
res.status = "Failed";
|
||||||
|
|
||||||
@@ -828,9 +688,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_outs);
|
RPC_TRACKER(get_outs);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUTS>(invoke_http_mode::JON, "/get_outs", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res.status = "Failed";
|
res.status = "Failed";
|
||||||
|
|
||||||
@@ -873,9 +730,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_indexes);
|
RPC_TRACKER(get_indexes);
|
||||||
bool ok;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES>(invoke_http_mode::BIN, "/get_o_indexes.bin", req, res, ok))
|
|
||||||
return ok;
|
|
||||||
|
|
||||||
bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes);
|
bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes);
|
||||||
if(!r)
|
if(!r)
|
||||||
@@ -891,9 +745,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_transactions);
|
RPC_TRACKER(get_transactions);
|
||||||
bool ok;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
|
||||||
return ok;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
@@ -1139,9 +990,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_is_key_image_spent(const COMMAND_RPC_IS_KEY_IMAGE_SPENT::request& req, COMMAND_RPC_IS_KEY_IMAGE_SPENT::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(is_key_image_spent);
|
RPC_TRACKER(is_key_image_spent);
|
||||||
bool ok;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
|
||||||
return ok;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
||||||
@@ -1226,30 +1074,7 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
RPC_TRACKER(send_raw_tx);
|
RPC_TRACKER(send_raw_tx);
|
||||||
|
|
||||||
{
|
CHECK_CORE_READY();
|
||||||
bool ok;
|
|
||||||
use_bootstrap_daemon_if_necessary<COMMAND_RPC_SEND_RAW_TX>(invoke_http_mode::JON, "/sendrawtransaction", req, res, ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
|
||||||
|
|
||||||
bool skip_validation = false;
|
|
||||||
if (!restricted)
|
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_should_use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
skip_validation = !check_core_ready();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_CORE_READY();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CHECK_CORE_READY();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string tx_blob;
|
std::string tx_blob;
|
||||||
if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob))
|
if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob))
|
||||||
@@ -1269,53 +1094,50 @@ namespace cryptonote
|
|||||||
}
|
}
|
||||||
res.sanity_check_failed = false;
|
res.sanity_check_failed = false;
|
||||||
|
|
||||||
if (!skip_validation)
|
tx_verification_context tvc{};
|
||||||
|
if(!m_core.handle_incoming_tx(tx_blob, tvc, (req.do_not_relay ? relay_method::none : relay_method::local), false) || tvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
tx_verification_context tvc{};
|
res.status = "Failed";
|
||||||
if(!m_core.handle_incoming_tx(tx_blob, tvc, (req.do_not_relay ? relay_method::none : relay_method::local), false) || tvc.m_verifivation_failed)
|
std::string reason = "";
|
||||||
|
if ((res.low_mixin = tvc.m_low_mixin))
|
||||||
|
add_reason(reason, "bad ring size");
|
||||||
|
if ((res.double_spend = tvc.m_double_spend))
|
||||||
|
add_reason(reason, "double spend");
|
||||||
|
if ((res.invalid_input = tvc.m_invalid_input))
|
||||||
|
add_reason(reason, "invalid input");
|
||||||
|
if ((res.invalid_output = tvc.m_invalid_output))
|
||||||
|
add_reason(reason, "invalid output");
|
||||||
|
if ((res.too_big = tvc.m_too_big))
|
||||||
|
add_reason(reason, "too big");
|
||||||
|
if ((res.overspend = tvc.m_overspend))
|
||||||
|
add_reason(reason, "overspend");
|
||||||
|
if ((res.fee_too_low = tvc.m_fee_too_low))
|
||||||
|
add_reason(reason, "fee too low");
|
||||||
|
if ((res.too_few_outputs = tvc.m_too_few_outputs))
|
||||||
|
add_reason(reason, "too few outputs");
|
||||||
|
if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big))
|
||||||
|
add_reason(reason, "tx-extra too big");
|
||||||
|
if ((res.nonzero_unlock_time = tvc.m_nonzero_unlock_time))
|
||||||
|
add_reason(reason, "tx unlock time is not zero");
|
||||||
|
const std::string punctuation = reason.empty() ? "" : ": ";
|
||||||
|
if (tvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
res.status = "Failed";
|
LOG_PRINT_L0("[on_send_raw_tx]: tx verification failed" << punctuation << reason);
|
||||||
std::string reason = "";
|
|
||||||
if ((res.low_mixin = tvc.m_low_mixin))
|
|
||||||
add_reason(reason, "bad ring size");
|
|
||||||
if ((res.double_spend = tvc.m_double_spend))
|
|
||||||
add_reason(reason, "double spend");
|
|
||||||
if ((res.invalid_input = tvc.m_invalid_input))
|
|
||||||
add_reason(reason, "invalid input");
|
|
||||||
if ((res.invalid_output = tvc.m_invalid_output))
|
|
||||||
add_reason(reason, "invalid output");
|
|
||||||
if ((res.too_big = tvc.m_too_big))
|
|
||||||
add_reason(reason, "too big");
|
|
||||||
if ((res.overspend = tvc.m_overspend))
|
|
||||||
add_reason(reason, "overspend");
|
|
||||||
if ((res.fee_too_low = tvc.m_fee_too_low))
|
|
||||||
add_reason(reason, "fee too low");
|
|
||||||
if ((res.too_few_outputs = tvc.m_too_few_outputs))
|
|
||||||
add_reason(reason, "too few outputs");
|
|
||||||
if ((res.tx_extra_too_big = tvc.m_tx_extra_too_big))
|
|
||||||
add_reason(reason, "tx-extra too big");
|
|
||||||
if ((res.nonzero_unlock_time = tvc.m_nonzero_unlock_time))
|
|
||||||
add_reason(reason, "tx unlock time is not zero");
|
|
||||||
const std::string punctuation = reason.empty() ? "" : ": ";
|
|
||||||
if (tvc.m_verifivation_failed)
|
|
||||||
{
|
|
||||||
LOG_PRINT_L0("[on_send_raw_tx]: tx verification failed" << punctuation << reason);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_PRINT_L0("[on_send_raw_tx]: Failed to process tx" << punctuation << reason);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_PRINT_L0("[on_send_raw_tx]: Failed to process tx" << punctuation << reason);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(tvc.m_relay == relay_method::none)
|
if(tvc.m_relay == relay_method::none)
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed");
|
LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed");
|
||||||
res.reason = "Not relayed";
|
res.reason = "Not relayed";
|
||||||
res.not_relayed = true;
|
res.not_relayed = true;
|
||||||
res.status = CORE_RPC_STATUS_OK;
|
res.status = CORE_RPC_STATUS_OK;
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NOTIFY_NEW_TRANSACTIONS::request r;
|
NOTIFY_NEW_TRANSACTIONS::request r;
|
||||||
@@ -1579,9 +1401,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_transaction_pool(const COMMAND_RPC_GET_TRANSACTION_POOL::request& req, COMMAND_RPC_GET_TRANSACTION_POOL::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_transaction_pool);
|
RPC_TRACKER(get_transaction_pool);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL>(invoke_http_mode::JON, "/get_transaction_pool", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
@@ -1602,9 +1421,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_transaction_pool_hashes);
|
RPC_TRACKER(get_transaction_pool_hashes);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN>(invoke_http_mode::JON, "/get_transaction_pool_hashes.bin", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
@@ -1623,9 +1439,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_transaction_pool_hashes);
|
RPC_TRACKER(get_transaction_pool_hashes);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES>(invoke_http_mode::JON, "/get_transaction_pool_hashes", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
@@ -1648,9 +1461,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_transaction_pool_stats);
|
RPC_TRACKER(get_transaction_pool_stats);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_STATS>(invoke_http_mode::JON, "/get_transaction_pool_stats", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
const bool request_has_rpc_origin = ctx != NULL;
|
const bool request_has_rpc_origin = ctx != NULL;
|
||||||
@@ -1660,28 +1470,6 @@ namespace cryptonote
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool core_rpc_server::on_set_bootstrap_daemon(const COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request& req, COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response& res, const connection_context *ctx)
|
|
||||||
{
|
|
||||||
PERF_TIMER(on_set_bootstrap_daemon);
|
|
||||||
|
|
||||||
boost::optional<epee::net_utils::http::login> credentials;
|
|
||||||
if (!req.username.empty() || !req.password.empty())
|
|
||||||
{
|
|
||||||
credentials = epee::net_utils::http::login(req.username, req.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set_bootstrap_daemon(req.address, credentials, req.proxy))
|
|
||||||
{
|
|
||||||
res.status = CORE_RPC_STATUS_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res.status = "Failed to set bootstrap daemon";
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(stop_daemon);
|
RPC_TRACKER(stop_daemon);
|
||||||
@@ -1695,14 +1483,7 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(getblockcount);
|
RPC_TRACKER(getblockcount);
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_should_use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
res.status = "This command is unsupported for bootstrap daemon";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.count = m_core.get_current_blockchain_height();
|
res.count = m_core.get_current_blockchain_height();
|
||||||
res.status = CORE_RPC_STATUS_OK;
|
res.status = CORE_RPC_STATUS_OK;
|
||||||
return true;
|
return true;
|
||||||
@@ -1711,14 +1492,7 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(getblockhash);
|
RPC_TRACKER(getblockhash);
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_should_use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
res = "This command is unsupported for bootstrap daemon";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(req.size() != 1)
|
if(req.size() != 1)
|
||||||
{
|
{
|
||||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
||||||
@@ -1808,9 +1582,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(getblocktemplate);
|
RPC_TRACKER(getblocktemplate);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GETBLOCKTEMPLATE>(invoke_http_mode::JON_RPC, "getblocktemplate", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if(!check_core_ready())
|
if(!check_core_ready())
|
||||||
{
|
{
|
||||||
@@ -2002,9 +1773,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_add_aux_pow(const COMMAND_RPC_ADD_AUX_POW::request& req, COMMAND_RPC_ADD_AUX_POW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_add_aux_pow(const COMMAND_RPC_ADD_AUX_POW::request& req, COMMAND_RPC_ADD_AUX_POW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(add_aux_pow);
|
RPC_TRACKER(add_aux_pow);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_ADD_AUX_POW>(invoke_http_mode::JON_RPC, "add_aux_pow", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
|
|
||||||
@@ -2148,15 +1916,7 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(submitblock);
|
RPC_TRACKER(submitblock);
|
||||||
{
|
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (m_should_use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
error_resp.code = CORE_RPC_ERROR_CODE_UNSUPPORTED_BOOTSTRAP;
|
|
||||||
error_resp.message = "This command is unsupported for bootstrap daemon";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CHECK_CORE_READY();
|
CHECK_CORE_READY();
|
||||||
if(req.size()!=1)
|
if(req.size()!=1)
|
||||||
{
|
{
|
||||||
@@ -2313,103 +2073,9 @@ namespace cryptonote
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
template <typename COMMAND_TYPE>
|
|
||||||
bool core_rpc_server::use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r)
|
|
||||||
{
|
|
||||||
res.untrusted = false;
|
|
||||||
r = false;
|
|
||||||
|
|
||||||
boost::upgrade_lock<boost::shared_mutex> upgrade_lock(m_bootstrap_daemon_mutex);
|
|
||||||
|
|
||||||
if (m_bootstrap_daemon.get() == nullptr)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_should_use_bootstrap_daemon)
|
|
||||||
{
|
|
||||||
MINFO("The local daemon is fully synced. Not switching back to the bootstrap daemon");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto current_time = std::chrono::system_clock::now();
|
|
||||||
if (current_time - m_bootstrap_height_check_time > std::chrono::seconds(30)) // update every 30s
|
|
||||||
{
|
|
||||||
{
|
|
||||||
boost::upgrade_to_unique_lock<boost::shared_mutex> lock(upgrade_lock);
|
|
||||||
m_bootstrap_height_check_time = current_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::optional<std::pair<uint64_t, uint64_t>> bootstrap_daemon_height_info = m_bootstrap_daemon->get_height();
|
|
||||||
if (!bootstrap_daemon_height_info)
|
|
||||||
{
|
|
||||||
MERROR("Failed to fetch bootstrap daemon height");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t bootstrap_daemon_height = bootstrap_daemon_height_info->first;
|
|
||||||
const uint64_t bootstrap_daemon_target_height = bootstrap_daemon_height_info->second;
|
|
||||||
if (bootstrap_daemon_height < bootstrap_daemon_target_height)
|
|
||||||
{
|
|
||||||
MINFO("Bootstrap daemon is out of sync");
|
|
||||||
return m_bootstrap_daemon->handle_result(false, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bootstrap_daemon_height < m_core.get_checkpoints().get_max_height())
|
|
||||||
{
|
|
||||||
MINFO("Bootstrap daemon height is lower than the latest checkpoint");
|
|
||||||
return m_bootstrap_daemon->handle_result(false, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_p2p.get_payload_object().no_sync())
|
|
||||||
{
|
|
||||||
uint64_t top_height = m_core.get_current_blockchain_height();
|
|
||||||
m_should_use_bootstrap_daemon = top_height + 10 < bootstrap_daemon_height;
|
|
||||||
MINFO((m_should_use_bootstrap_daemon ? "Using" : "Not using") << " the bootstrap daemon (our height: " << top_height << ", bootstrap daemon's height: " << bootstrap_daemon_height << ")");
|
|
||||||
|
|
||||||
if (!m_should_use_bootstrap_daemon)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == invoke_http_mode::JON)
|
|
||||||
{
|
|
||||||
r = m_bootstrap_daemon->invoke_http_json(command_name, req, res);
|
|
||||||
}
|
|
||||||
else if (mode == invoke_http_mode::BIN)
|
|
||||||
{
|
|
||||||
r = m_bootstrap_daemon->invoke_http_bin(command_name, req, res);
|
|
||||||
}
|
|
||||||
else if (mode == invoke_http_mode::JON_RPC)
|
|
||||||
{
|
|
||||||
r = m_bootstrap_daemon->invoke_http_json_rpc(command_name, req, res);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MERROR("Unknown invoke_http_mode: " << mode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
boost::upgrade_to_unique_lock<boost::shared_mutex> lock(upgrade_lock);
|
|
||||||
m_was_bootstrap_ever_used = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r && res.status != CORE_RPC_STATUS_PAYMENT_REQUIRED && res.status != CORE_RPC_STATUS_OK)
|
|
||||||
{
|
|
||||||
MINFO("Failing RPC " << command_name << " due to peer return status " << res.status);
|
|
||||||
r = false;
|
|
||||||
}
|
|
||||||
res.untrusted = true;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_last_block_header);
|
RPC_TRACKER(get_last_block_header);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_LAST_BLOCK_HEADER>(invoke_http_mode::JON_RPC, "getlastblockheader", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
CHECK_CORE_READY();
|
CHECK_CORE_READY();
|
||||||
uint64_t last_block_height;
|
uint64_t last_block_height;
|
||||||
@@ -2438,9 +2104,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_block_header_by_hash);
|
RPC_TRACKER(get_block_header_by_hash);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH>(invoke_http_mode::JON_RPC, "getblockheaderbyhash", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
|
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
|
||||||
@@ -2505,9 +2168,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_block_headers_range(const COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request& req, COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_block_headers_range);
|
RPC_TRACKER(get_block_headers_range);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADERS_RANGE>(invoke_http_mode::JON_RPC, "getblockheadersrange", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const uint64_t bc_height = m_core.get_current_blockchain_height();
|
const uint64_t bc_height = m_core.get_current_blockchain_height();
|
||||||
if (req.start_height >= bc_height || req.end_height >= bc_height || req.start_height > req.end_height)
|
if (req.start_height >= bc_height || req.end_height >= bc_height || req.start_height > req.end_height)
|
||||||
@@ -2564,9 +2224,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_block_header_by_height);
|
RPC_TRACKER(get_block_header_by_height);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT>(invoke_http_mode::JON_RPC, "getblockheaderbyheight", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if(m_core.get_current_blockchain_height() <= req.height)
|
if(m_core.get_current_blockchain_height() <= req.height)
|
||||||
{
|
{
|
||||||
@@ -2598,9 +2255,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_block);
|
RPC_TRACKER(get_block);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK>(invoke_http_mode::JON_RPC, "getblock", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
crypto::hash block_hash;
|
crypto::hash block_hash;
|
||||||
if (!req.hash.empty())
|
if (!req.hash.empty())
|
||||||
@@ -2683,9 +2337,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_hard_fork_info(const COMMAND_RPC_HARD_FORK_INFO::request& req, COMMAND_RPC_HARD_FORK_INFO::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(hard_fork_info);
|
RPC_TRACKER(hard_fork_info);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_HARD_FORK_INFO>(invoke_http_mode::JON_RPC, "hard_fork_info", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const Blockchain &blockchain = m_core.get_blockchain_storage();
|
const Blockchain &blockchain = m_core.get_blockchain_storage();
|
||||||
uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version();
|
uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version();
|
||||||
@@ -2871,9 +2522,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_output_histogram);
|
RPC_TRACKER(get_output_histogram);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_HISTOGRAM>(invoke_http_mode::JON_RPC, "get_output_histogram", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
size_t amounts = req.amounts.size();
|
size_t amounts = req.amounts.size();
|
||||||
@@ -2915,9 +2563,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_version);
|
RPC_TRACKER(get_version);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_VERSION>(invoke_http_mode::JON_RPC, "get_version", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res.version = CORE_RPC_VERSION;
|
res.version = CORE_RPC_VERSION;
|
||||||
res.release = MONERO_VERSION_IS_RELEASE;
|
res.release = MONERO_VERSION_IS_RELEASE;
|
||||||
@@ -2948,9 +2593,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_base_fee_estimate(const COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_base_fee_estimate);
|
RPC_TRACKER(get_base_fee_estimate);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BASE_FEE_ESTIMATE>(invoke_http_mode::JON_RPC, "get_fee_estimate", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
m_core.get_blockchain_storage().get_dynamic_base_fee_estimate_2021_scaling(req.grace_blocks, res.fees);
|
m_core.get_blockchain_storage().get_dynamic_base_fee_estimate_2021_scaling(req.grace_blocks, res.fees);
|
||||||
@@ -2997,9 +2639,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_limit);
|
RPC_TRACKER(get_limit);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_LIMIT>(invoke_http_mode::JON, "/get_limit", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
res.limit_down = epee::net_utils::connection_basic::get_rate_down_limit();
|
res.limit_down = epee::net_utils::connection_basic::get_rate_down_limit();
|
||||||
res.limit_up = epee::net_utils::connection_basic::get_rate_up_limit();
|
res.limit_up = epee::net_utils::connection_basic::get_rate_up_limit();
|
||||||
@@ -3261,9 +2900,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_txpool_backlog(const COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_txpool_backlog);
|
RPC_TRACKER(get_txpool_backlog);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG>(invoke_http_mode::JON_RPC, "get_txpool_backlog", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (!m_core.get_txpool_backlog(res.backlog))
|
if (!m_core.get_txpool_backlog(res.backlog))
|
||||||
{
|
{
|
||||||
@@ -3279,9 +2915,6 @@ namespace cryptonote
|
|||||||
bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
RPC_TRACKER(get_output_distribution);
|
RPC_TRACKER(get_output_distribution);
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::JON_RPC, "get_output_distribution", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
||||||
@@ -3323,10 +2956,6 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
RPC_TRACKER(get_output_distribution_bin);
|
RPC_TRACKER(get_output_distribution_bin);
|
||||||
|
|
||||||
bool r;
|
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r))
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const bool restricted = m_restricted && ctx;
|
const bool restricted = m_restricted && ctx;
|
||||||
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
||||||
{
|
{
|
||||||
@@ -3405,9 +3034,6 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
RPC_TRACKER(get_txids_loose);
|
RPC_TRACKER(get_txids_loose);
|
||||||
|
|
||||||
// Maybe don't use bootstrap since this endpoint is meant to retrieve TXIDs w/ k-anonymity,
|
|
||||||
// so shunting this request to a random node seems counterproductive.
|
|
||||||
|
|
||||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (m_restricted ? 1 : 10);
|
const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (m_restricted ? 1 : 10);
|
||||||
|
|
||||||
@@ -3503,25 +3129,6 @@ namespace cryptonote
|
|||||||
, false
|
, false
|
||||||
};
|
};
|
||||||
|
|
||||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_address = {
|
|
||||||
"bootstrap-daemon-address"
|
|
||||||
, "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n"
|
|
||||||
"Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
|
|
||||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_login = {
|
|
||||||
"bootstrap-daemon-login"
|
|
||||||
, "Specify username:password for the bootstrap daemon login"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
|
|
||||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_proxy = {
|
|
||||||
"bootstrap-daemon-proxy"
|
|
||||||
, "<ip>:<port> socks proxy to use for bootstrap daemon connections"
|
|
||||||
, ""
|
|
||||||
};
|
|
||||||
|
|
||||||
const command_line::arg_descriptor<std::size_t> core_rpc_server::arg_rpc_max_connections_per_public_ip = {
|
const command_line::arg_descriptor<std::size_t> core_rpc_server::arg_rpc_max_connections_per_public_ip = {
|
||||||
"rpc-max-connections-per-public-ip"
|
"rpc-max-connections-per-public-ip"
|
||||||
, "Max RPC connections per public IP permitted"
|
, "Max RPC connections per public IP permitted"
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
#include <boost/program_options/options_description.hpp>
|
#include <boost/program_options/options_description.hpp>
|
||||||
#include <boost/program_options/variables_map.hpp>
|
#include <boost/program_options/variables_map.hpp>
|
||||||
|
|
||||||
#include "bootstrap_daemon.h"
|
|
||||||
#include "net/http_server_impl_base.h"
|
#include "net/http_server_impl_base.h"
|
||||||
#include "net/http_client.h"
|
#include "net/http_client.h"
|
||||||
#include "core_rpc_server_commands_defs.h"
|
#include "core_rpc_server_commands_defs.h"
|
||||||
@@ -64,9 +63,6 @@ namespace cryptonote
|
|||||||
static const command_line::arg_descriptor<std::string> arg_rpc_ssl_ca_certificates;
|
static const command_line::arg_descriptor<std::string> arg_rpc_ssl_ca_certificates;
|
||||||
static const command_line::arg_descriptor<std::vector<std::string>> arg_rpc_ssl_allowed_fingerprints;
|
static const command_line::arg_descriptor<std::vector<std::string>> arg_rpc_ssl_allowed_fingerprints;
|
||||||
static const command_line::arg_descriptor<bool> arg_rpc_ssl_allow_any_cert;
|
static const command_line::arg_descriptor<bool> arg_rpc_ssl_allow_any_cert;
|
||||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_address;
|
|
||||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_login;
|
|
||||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_proxy;
|
|
||||||
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_public_ip;
|
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_public_ip;
|
||||||
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_private_ip;
|
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections_per_private_ip;
|
||||||
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections;
|
static const command_line::arg_descriptor<std::size_t> arg_rpc_max_connections;
|
||||||
@@ -121,7 +117,6 @@ namespace cryptonote
|
|||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes.bin", on_get_transaction_pool_hashes_bin, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes.bin", on_get_transaction_pool_hashes_bin, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN)
|
||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes", on_get_transaction_pool_hashes, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes", on_get_transaction_pool_hashes, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES)
|
||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS)
|
||||||
MAP_URI_AUTO_JON2_IF("/set_bootstrap_daemon", on_set_bootstrap_daemon, COMMAND_RPC_SET_BOOTSTRAP_DAEMON, !m_restricted)
|
|
||||||
MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted)
|
MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted)
|
||||||
MAP_URI_AUTO_JON2("/get_info", on_get_info, COMMAND_RPC_GET_INFO)
|
MAP_URI_AUTO_JON2("/get_info", on_get_info, COMMAND_RPC_GET_INFO)
|
||||||
MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO)
|
MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO)
|
||||||
@@ -205,7 +200,6 @@ namespace cryptonote
|
|||||||
bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_set_bootstrap_daemon(const COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request& req, COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response& res, const connection_context *ctx = NULL);
|
|
||||||
bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx = NULL);
|
bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx = NULL);
|
bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx = NULL);
|
bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx = NULL);
|
||||||
@@ -258,28 +252,10 @@ private:
|
|||||||
//utils
|
//utils
|
||||||
uint64_t get_block_reward(const block& blk);
|
uint64_t get_block_reward(const block& blk);
|
||||||
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash);
|
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash);
|
||||||
std::map<std::string, bool> get_public_nodes(uint32_t credits_per_hash_threshold = 0);
|
|
||||||
bool set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const std::string &username_password,
|
|
||||||
const std::string &proxy);
|
|
||||||
bool set_bootstrap_daemon(
|
|
||||||
const std::string &address,
|
|
||||||
const boost::optional<epee::net_utils::http::login> &credentials,
|
|
||||||
const std::string &proxy);
|
|
||||||
enum invoke_http_mode { JON, BIN, JON_RPC };
|
|
||||||
template <typename COMMAND_TYPE>
|
|
||||||
bool use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r);
|
|
||||||
bool get_block_template(const account_public_address &address, const crypto::hash *prev_block, const cryptonote::blobdata &extra_nonce, size_t &reserved_offset, cryptonote::difficulty_type &difficulty, uint64_t &height, uint64_t &expected_reward, uint64_t& cumulative_weight, block &b, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, epee::json_rpc::error &error_resp);
|
bool get_block_template(const account_public_address &address, const crypto::hash *prev_block, const cryptonote::blobdata &extra_nonce, size_t &reserved_offset, cryptonote::difficulty_type &difficulty, uint64_t &height, uint64_t &expected_reward, uint64_t& cumulative_weight, block &b, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, epee::json_rpc::error &error_resp);
|
||||||
|
|
||||||
core& m_core;
|
core& m_core;
|
||||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
||||||
boost::shared_mutex m_bootstrap_daemon_mutex;
|
|
||||||
std::unique_ptr<bootstrap_daemon> m_bootstrap_daemon;
|
|
||||||
std::string m_bootstrap_daemon_proxy;
|
|
||||||
bool m_should_use_bootstrap_daemon;
|
|
||||||
std::chrono::system_clock::time_point m_bootstrap_height_check_time;
|
|
||||||
bool m_was_bootstrap_ever_used;
|
|
||||||
bool m_restricted;
|
bool m_restricted;
|
||||||
epee::critical_section m_host_fails_score_lock;
|
epee::critical_section m_host_fails_score_lock;
|
||||||
std::map<std::string, uint64_t> m_host_fails_score;
|
std::map<std::string, uint64_t> m_host_fails_score;
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
|||||||
// advance which version they will stop working with
|
// advance which version they will stop working with
|
||||||
// Don't go over 32767 for any of these
|
// Don't go over 32767 for any of these
|
||||||
#define CORE_RPC_VERSION_MAJOR 3
|
#define CORE_RPC_VERSION_MAJOR 3
|
||||||
#define CORE_RPC_VERSION_MINOR 17
|
#define CORE_RPC_VERSION_MINOR 18
|
||||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||||
|
|
||||||
@@ -114,13 +114,9 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
|||||||
struct rpc_response_base
|
struct rpc_response_base
|
||||||
{
|
{
|
||||||
std::string status;
|
std::string status;
|
||||||
bool untrusted;
|
|
||||||
|
|
||||||
rpc_response_base(): untrusted(false) {}
|
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
KV_SERIALIZE(status)
|
KV_SERIALIZE(status)
|
||||||
KV_SERIALIZE(untrusted)
|
|
||||||
END_KV_SERIALIZE_MAP()
|
END_KV_SERIALIZE_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -723,9 +719,6 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
|||||||
uint64_t start_time;
|
uint64_t start_time;
|
||||||
uint64_t free_space;
|
uint64_t free_space;
|
||||||
bool offline;
|
bool offline;
|
||||||
std::string bootstrap_daemon_address;
|
|
||||||
uint64_t height_without_bootstrap;
|
|
||||||
bool was_bootstrap_ever_used;
|
|
||||||
uint64_t database_size;
|
uint64_t database_size;
|
||||||
bool update_available;
|
bool update_available;
|
||||||
bool busy_syncing;
|
bool busy_syncing;
|
||||||
@@ -765,9 +758,6 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
|||||||
KV_SERIALIZE(start_time)
|
KV_SERIALIZE(start_time)
|
||||||
KV_SERIALIZE(free_space)
|
KV_SERIALIZE(free_space)
|
||||||
KV_SERIALIZE(offline)
|
KV_SERIALIZE(offline)
|
||||||
KV_SERIALIZE(bootstrap_daemon_address)
|
|
||||||
KV_SERIALIZE(height_without_bootstrap)
|
|
||||||
KV_SERIALIZE(was_bootstrap_ever_used)
|
|
||||||
KV_SERIALIZE(database_size)
|
KV_SERIALIZE(database_size)
|
||||||
KV_SERIALIZE(update_available)
|
KV_SERIALIZE(update_available)
|
||||||
KV_SERIALIZE(busy_syncing)
|
KV_SERIALIZE(busy_syncing)
|
||||||
@@ -1775,35 +1765,6 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st
|
|||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct COMMAND_RPC_SET_BOOTSTRAP_DAEMON
|
|
||||||
{
|
|
||||||
struct request_t
|
|
||||||
{
|
|
||||||
std::string address;
|
|
||||||
std::string username;
|
|
||||||
std::string password;
|
|
||||||
std::string proxy;
|
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
|
||||||
KV_SERIALIZE(address)
|
|
||||||
KV_SERIALIZE(username)
|
|
||||||
KV_SERIALIZE(password)
|
|
||||||
KV_SERIALIZE(proxy)
|
|
||||||
END_KV_SERIALIZE_MAP()
|
|
||||||
};
|
|
||||||
typedef epee::misc_utils::struct_init<request_t> request;
|
|
||||||
|
|
||||||
struct response_t
|
|
||||||
{
|
|
||||||
std::string status;
|
|
||||||
|
|
||||||
BEGIN_KV_SERIALIZE_MAP()
|
|
||||||
KV_SERIALIZE(status)
|
|
||||||
END_KV_SERIALIZE_MAP()
|
|
||||||
};
|
|
||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct COMMAND_RPC_STOP_DAEMON
|
struct COMMAND_RPC_STOP_DAEMON
|
||||||
{
|
{
|
||||||
struct request_t: public rpc_request_base
|
struct request_t: public rpc_request_base
|
||||||
|
|||||||
@@ -4602,13 +4602,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||||||
message_writer(console_color_red, true) << boost::format(tr("Using your own without SSL exposes your RPC traffic to monitoring"));
|
message_writer(console_color_red, true) << boost::format(tr("Using your own without SSL exposes your RPC traffic to monitoring"));
|
||||||
message_writer(console_color_red, true) << boost::format(tr("You are strongly encouraged to connect to the Monero network using your own daemon"));
|
message_writer(console_color_red, true) << boost::format(tr("You are strongly encouraged to connect to the Monero network using your own daemon"));
|
||||||
message_writer(console_color_red, true) << boost::format(tr("If you or someone you trust are operating this daemon, you can use --trusted-daemon"));
|
message_writer(console_color_red, true) << boost::format(tr("If you or someone you trust are operating this daemon, you can use --trusted-daemon"));
|
||||||
|
|
||||||
COMMAND_RPC_GET_INFO::request req;
|
|
||||||
COMMAND_RPC_GET_INFO::response res;
|
|
||||||
bool r = m_wallet->invoke_http_json("/get_info", req, res);
|
|
||||||
std::string err = interpret_rpc_response(r, res.status);
|
|
||||||
if (r && err.empty() && (res.was_bootstrap_ever_used || !res.bootstrap_daemon_address.empty()))
|
|
||||||
message_writer(console_color_red, true) << boost::format(tr("Moreover, a daemon is also less secure when running in bootstrap mode"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_wallet->get_ring_database().empty())
|
if (m_wallet->get_ring_database().empty())
|
||||||
|
|||||||
@@ -67,9 +67,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable bootstrap daemon
|
|
||||||
disable_bootstrap_daemon(*rpc_handler->rpc);
|
|
||||||
|
|
||||||
for (unsigned selector : selectors) {
|
for (unsigned selector : selectors) {
|
||||||
try {
|
try {
|
||||||
// Fuzz the target function
|
// Fuzz the target function
|
||||||
|
|||||||
@@ -7,19 +7,6 @@
|
|||||||
cryptonote::core_rpc_server::connection_context ctx;
|
cryptonote::core_rpc_server::connection_context ctx;
|
||||||
epee::json_rpc::error error_resp;
|
epee::json_rpc::error error_resp;
|
||||||
|
|
||||||
// Helper function to disable bootstrap daemon
|
|
||||||
void disable_bootstrap_daemon(cryptonote::core_rpc_server& rpc) {
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request req;
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response res;
|
|
||||||
|
|
||||||
req.address = "";
|
|
||||||
req.username = "";
|
|
||||||
req.password = "";
|
|
||||||
req.proxy = "";
|
|
||||||
|
|
||||||
rpc.on_set_bootstrap_daemon(req, res, &ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve fuzz targets base on SAFE settings
|
// Retrieve fuzz targets base on SAFE settings
|
||||||
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> get_fuzz_targets(bool safe) {
|
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> get_fuzz_targets(bool safe) {
|
||||||
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> results;
|
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> results;
|
||||||
@@ -313,21 +300,6 @@ void fuzz_get_transaction_pool_stats(cryptonote::core_rpc_server& rpc, FuzzedDat
|
|||||||
rpc.on_get_transaction_pool_stats(req, res, &ctx);
|
rpc.on_get_transaction_pool_stats(req, res, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fuzz_set_bootstrap_daemon(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) {
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request req;
|
|
||||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response res;
|
|
||||||
|
|
||||||
req.address = provider.ConsumeRandomLengthString(64);
|
|
||||||
req.username = provider.ConsumeRandomLengthString(32);
|
|
||||||
req.password = provider.ConsumeRandomLengthString(32);
|
|
||||||
req.proxy = provider.ConsumeRandomLengthString(32);
|
|
||||||
|
|
||||||
rpc.on_set_bootstrap_daemon(req, res, &ctx);
|
|
||||||
|
|
||||||
// Immediate reset bootstrap daemon to avoid affecting other fuzzing with external calls
|
|
||||||
disable_bootstrap_daemon(rpc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fuzz_stop_daemon(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) {
|
void fuzz_stop_daemon(cryptonote::core_rpc_server& rpc, FuzzedDataProvider& provider) {
|
||||||
cryptonote::COMMAND_RPC_STOP_DAEMON::request req;
|
cryptonote::COMMAND_RPC_STOP_DAEMON::request req;
|
||||||
cryptonote::COMMAND_RPC_STOP_DAEMON::response res;
|
cryptonote::COMMAND_RPC_STOP_DAEMON::response res;
|
||||||
@@ -865,7 +837,6 @@ std::map<int, std::function<void(cryptonote::core_rpc_server&, FuzzedDataProvide
|
|||||||
{56, fuzz_stop_mining},
|
{56, fuzz_stop_mining},
|
||||||
{57, fuzz_mining_status},
|
{57, fuzz_mining_status},
|
||||||
{58, fuzz_save_bc},
|
{58, fuzz_save_bc},
|
||||||
{59, fuzz_set_bootstrap_daemon},
|
|
||||||
{60, fuzz_stop_daemon},
|
{60, fuzz_stop_daemon},
|
||||||
{61, fuzz_update},
|
{61, fuzz_update},
|
||||||
{62, fuzz_add_aux_pow},
|
{62, fuzz_add_aux_pow},
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ namespace tools {
|
|||||||
extern __thread std::vector<LoggingPerformanceTimer*> *performance_timers;
|
extern __thread std::vector<LoggingPerformanceTimer*> *performance_timers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_bootstrap_daemon(cryptonote::core_rpc_server& rpc);
|
|
||||||
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> get_fuzz_targets(bool safe);
|
std::map<int, std::function<void(cryptonote::core_rpc_server& rpc, FuzzedDataProvider&)>> get_fuzz_targets(bool safe);
|
||||||
|
|
||||||
void fuzz_get_height(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_height(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
@@ -35,7 +34,6 @@ void fuzz_get_transaction_pool(cryptonote::core_rpc_server&, FuzzedDataProvider&
|
|||||||
void fuzz_get_transaction_pool_hashes_bin(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_transaction_pool_hashes_bin(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
void fuzz_get_transaction_pool_hashes(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_transaction_pool_hashes(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
void fuzz_get_transaction_pool_stats(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_transaction_pool_stats(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
void fuzz_set_bootstrap_daemon(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
|
||||||
void fuzz_stop_daemon(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_stop_daemon(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
void fuzz_get_info(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_info(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
void fuzz_get_net_stats(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
void fuzz_get_net_stats(cryptonote::core_rpc_server&, FuzzedDataProvider& provider);
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ set(unit_tests_sources
|
|||||||
blockchain_db.cpp
|
blockchain_db.cpp
|
||||||
block_queue.cpp
|
block_queue.cpp
|
||||||
block_reward.cpp
|
block_reward.cpp
|
||||||
bootstrap_node_selector.cpp
|
|
||||||
bulletproofs.cpp
|
bulletproofs.cpp
|
||||||
bulletproofs_plus.cpp
|
bulletproofs_plus.cpp
|
||||||
canonical_amounts.cpp
|
canonical_amounts.cpp
|
||||||
|
|||||||
@@ -1,173 +0,0 @@
|
|||||||
// Copyright (c) 2020-2024, The Monero Project
|
|
||||||
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. 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.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder 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 HOLDER OR CONTRIBUTORS 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.
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include "rpc/bootstrap_node_selector.h"
|
|
||||||
|
|
||||||
class bootstrap_node_selector : public ::testing::Test
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
void SetUp() override
|
|
||||||
{
|
|
||||||
nodes.insert(white_nodes.begin(), white_nodes.end());
|
|
||||||
nodes.insert(gray_nodes.begin(), gray_nodes.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<std::string, bool> white_nodes = {
|
|
||||||
{
|
|
||||||
"white_node_1:18089", true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"white_node_2:18081", true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const std::map<std::string, bool> gray_nodes = {
|
|
||||||
{
|
|
||||||
"gray_node_1:18081", false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"gray_node_2:18089", false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<std::string, bool> nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_empty)
|
|
||||||
{
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([]() {
|
|
||||||
return std::map<std::string, bool>();
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_FALSE(selector.next_node());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_no_credentials)
|
|
||||||
{
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([this]() {
|
|
||||||
return nodes;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (size_t fails = 0; fails < nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
const auto current = selector.next_node();
|
|
||||||
EXPECT_FALSE(current->credentials);
|
|
||||||
|
|
||||||
selector.handle_result(current->address, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_success)
|
|
||||||
{
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([this]() {
|
|
||||||
return nodes;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto current = selector.next_node();
|
|
||||||
for (size_t fails = 0; fails < nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
selector.handle_result(current->address, true);
|
|
||||||
|
|
||||||
current = selector.next_node();
|
|
||||||
EXPECT_TRUE(white_nodes.count(current->address) > 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_failure)
|
|
||||||
{
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([this]() {
|
|
||||||
return nodes;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto current = selector.next_node();
|
|
||||||
for (size_t fails = 0; fails < nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
const auto previous = current;
|
|
||||||
|
|
||||||
selector.handle_result(current->address, false);
|
|
||||||
|
|
||||||
current = selector.next_node();
|
|
||||||
EXPECT_NE(current->address, previous->address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_white_nodes_first)
|
|
||||||
{
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([this]() {
|
|
||||||
return nodes;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (size_t iterations = 0; iterations < 2; ++iterations)
|
|
||||||
{
|
|
||||||
for (size_t fails = 0; fails < white_nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
const auto current = selector.next_node();
|
|
||||||
EXPECT_TRUE(white_nodes.count(current->address) > 0);
|
|
||||||
|
|
||||||
selector.handle_result(current->address, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t fails = 0; fails < gray_nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
const auto current = selector.next_node();
|
|
||||||
EXPECT_TRUE(gray_nodes.count(current->address) > 0);
|
|
||||||
|
|
||||||
selector.handle_result(current->address, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(bootstrap_node_selector, selector_auto_max_nodes)
|
|
||||||
{
|
|
||||||
const size_t max_nodes = nodes.size() / 2;
|
|
||||||
|
|
||||||
bool populated_once = false;
|
|
||||||
cryptonote::bootstrap_node::selector_auto selector([this, &populated_once]() {
|
|
||||||
if (!populated_once)
|
|
||||||
{
|
|
||||||
populated_once = true;
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::map<std::string, bool>();
|
|
||||||
}, max_nodes);
|
|
||||||
|
|
||||||
std::set<std::string> unique_nodes;
|
|
||||||
|
|
||||||
for (size_t fails = 0; fails < nodes.size(); ++fails)
|
|
||||||
{
|
|
||||||
const auto current = selector.next_node();
|
|
||||||
unique_nodes.insert(current->address);
|
|
||||||
|
|
||||||
selector.handle_result(current->address, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(unique_nodes.size(), max_nodes);
|
|
||||||
}
|
|
||||||
@@ -83,9 +83,6 @@ complete -c monerod -l max-connections-per-ip -r -d "Maximum number of connectio
|
|||||||
complete -c monerod -l rpc-bind-port -r -d "Port for RPC server. Default: 18081, 28081 if 'testnet', 38081 if 'stagenet'"
|
complete -c monerod -l rpc-bind-port -r -d "Port for RPC server. Default: 18081, 28081 if 'testnet', 38081 if 'stagenet'"
|
||||||
complete -c monerod -l rpc-restricted-bind-port -r -d "Port for restricted RPC server"
|
complete -c monerod -l rpc-restricted-bind-port -r -d "Port for restricted RPC server"
|
||||||
complete -c monerod -l restricted-rpc -d "Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls"
|
complete -c monerod -l restricted-rpc -d "Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls"
|
||||||
complete -c monerod -l bootstrap-daemon-address -r -d "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced. Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
|
|
||||||
complete -c monerod -l bootstrap-daemon-login -r -d "Specify username:password for the bootstrap daemon login"
|
|
||||||
complete -c monerod -l bootstrap-daemon-proxy -r -d "<ip>:<port> socks proxy to use for bootstrap daemon connections"
|
|
||||||
complete -c monerod -l rpc-bind-ip -r -d "Specify IP to bind RPC server. Default: 127.0.0.1"
|
complete -c monerod -l rpc-bind-ip -r -d "Specify IP to bind RPC server. Default: 127.0.0.1"
|
||||||
complete -c monerod -l rpc-bind-ipv6-address -r -d "Specify IPv6 address to bind RPC server. Default: ::1"
|
complete -c monerod -l rpc-bind-ipv6-address -r -d "Specify IPv6 address to bind RPC server. Default: ::1"
|
||||||
complete -c monerod -l rpc-restricted-bind-ip -r -d "Specify IP to bind restricted RPC server. Default: 127.0.0.1"
|
complete -c monerod -l rpc-restricted-bind-ip -r -d "Specify IP to bind restricted RPC server. Default: 127.0.0.1"
|
||||||
|
|||||||
@@ -329,14 +329,6 @@ class Daemon(object):
|
|||||||
}
|
}
|
||||||
return self.rpc.send_json_rpc_request(banned)
|
return self.rpc.send_json_rpc_request(banned)
|
||||||
|
|
||||||
def set_bootstrap_daemon(self, address, username = '', password = ''):
|
|
||||||
set_bootstrap_daemon = {
|
|
||||||
'address': address,
|
|
||||||
'username': username,
|
|
||||||
'password': password,
|
|
||||||
}
|
|
||||||
return self.rpc.send_request('/set_bootstrap_daemon', set_bootstrap_daemon)
|
|
||||||
|
|
||||||
def get_public_nodes(self, gray = False, white = True):
|
def get_public_nodes(self, gray = False, white = True):
|
||||||
get_public_nodes = {
|
get_public_nodes = {
|
||||||
'gray': gray,
|
'gray': gray,
|
||||||
|
|||||||
Reference in New Issue
Block a user