From a01b4c2a312646a50c2a9609317c40fdf1c43721 Mon Sep 17 00:00:00 2001 From: tobtoht Date: Sun, 31 May 2026 12:22:32 +0200 Subject: [PATCH] daemon: remove bootstrap mode --- src/daemon/command_parser_executor.cpp | 65 --- src/daemon/command_parser_executor.h | 2 - src/daemon/command_server.cpp | 7 - src/daemon/rpc_command_executor.cpp | 60 +-- src/daemon/rpc_command_executor.h | 6 - src/rpc/CMakeLists.txt | 3 - src/rpc/bootstrap_daemon.cpp | 126 ----- src/rpc/bootstrap_daemon.h | 87 ---- src/rpc/bootstrap_node_selector.cpp | 117 ----- src/rpc/bootstrap_node_selector.h | 105 ---- src/rpc/core_rpc_server.cpp | 483 ++----------------- src/rpc/core_rpc_server.h | 24 - src/rpc/core_rpc_server_commands_defs.h | 41 +- src/simplewallet/simplewallet.cpp | 7 - tests/fuzz/fuzz_rpc/fuzz_rpc.cpp | 3 - tests/fuzz/fuzz_rpc/rpc_endpoints.cpp | 29 -- tests/fuzz/fuzz_rpc/rpc_endpoints.h | 2 - tests/unit_tests/CMakeLists.txt | 1 - tests/unit_tests/bootstrap_node_selector.cpp | 173 ------- utils/fish/monerod.fish | 3 - utils/python-rpc/framework/daemon.py | 8 - 21 files changed, 48 insertions(+), 1304 deletions(-) delete mode 100644 src/rpc/bootstrap_daemon.cpp delete mode 100644 src/rpc/bootstrap_daemon.h delete mode 100644 src/rpc/bootstrap_node_selector.cpp delete mode 100644 src/rpc/bootstrap_node_selector.h delete mode 100644 tests/unit_tests/bootstrap_node_selector.cpp diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 728df58af..6b2637b6c 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -986,71 +986,6 @@ bool t_command_parser_executor::check_blockchain_pruning(const std::vector& args) -{ - struct parsed_t - { - std::string address; - std::string user; - std::string password; - std::string proxy; - }; - - boost::optional parsed = [&args]() -> boost::optional { - 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& args) { bool bad_blocks = false; diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index a053d0154..77b365a82 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -150,8 +150,6 @@ public: bool print_net_stats(const std::vector& args); - bool set_bootstrap_daemon(const std::vector& args); - bool flush_cache(const std::vector& args); }; diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 1950b22a6..bb26c8dfb 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -318,13 +318,6 @@ t_command_server::t_command_server( , std::bind(&t_command_parser_executor::check_blockchain_pruning, &m_parser, p::_1) , "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( "flush_cache" , std::bind(&t_command_parser_executor::flush_cache, &m_parser, p::_1) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 1385a85ee..c943cca13 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -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 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() { 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; 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; - 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)net_height - % get_sync_percentage(ires) + % get_sync_percentage(ires.height, ires.target_height) % (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") % get_mining_speed(cryptonote::difficulty_type(ires.wide_difficulty) / ires.target) % (unsigned)hfres.version @@ -2402,44 +2384,6 @@ bool t_rpc_command_executor::check_blockchain_pruning() 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) { cryptonote::COMMAND_RPC_FLUSH_CACHE::request req; diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 0469c9fff..c60658120 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -164,12 +164,6 @@ public: 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); }; diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index a1d3d9f60..bd1efa69a 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -31,8 +31,6 @@ set(rpc_base_sources rpc_handler.cpp) set(rpc_sources - bootstrap_daemon.cpp - bootstrap_node_selector.cpp core_rpc_server.cpp rpc_version_str.cpp instanciations.cpp) @@ -63,7 +61,6 @@ set(rpc_pub_headers zmq_pub.h) set(daemon_rpc_server_headers) set(rpc_private_headers - bootstrap_daemon.h core_rpc_server.h core_rpc_server_commands_defs.h core_rpc_server_error_codes.h) diff --git a/src/rpc/bootstrap_daemon.cpp b/src/rpc/bootstrap_daemon.cpp deleted file mode 100644 index b3aecb3bb..000000000 --- a/src/rpc/bootstrap_daemon.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "bootstrap_daemon.h" - -#include - -#include - -#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()> 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 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> 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 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 &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 node; - { - const boost::unique_lock lock(m_selector_mutex); - node = m_selector->next_node(); - } - if (node) { - return set_server(node->address, node->credentials); - } - - return false; - } - -} diff --git a/src/rpc/bootstrap_daemon.h b/src/rpc/bootstrap_daemon.h deleted file mode 100644 index 259bdfebe..000000000 --- a/src/rpc/bootstrap_daemon.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -#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()> get_public_nodes, - const std::string &proxy); - bootstrap_daemon( - const std::string &address, - boost::optional credentials, - const std::string &proxy); - - std::string address() const noexcept; - boost::optional> get_height(); - bool handle_result(bool success, const std::string &status); - - template - 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 - 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 - 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 &credentials = boost::none); - bool switch_server_if_needed(); - - private: - net::http::client m_http_client; - const std::unique_ptr m_selector; - boost::mutex m_selector_mutex; - }; - -} diff --git a/src/rpc/bootstrap_node_selector.cpp b/src/rpc/bootstrap_node_selector.cpp deleted file mode 100644 index 9f2f9a86e..000000000 --- a/src/rpc/bootstrap_node_selector.cpp +++ /dev/null @@ -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::max() - 2, fails) + 2; - } - else - { - fails = std::max(std::numeric_limits::min() + 2, fails) - 2; - } - } - - void selector_auto::handle_result(const std::string &address, bool success) - { - auto &nodes_by_address = m_nodes.get(); - 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 selector_auto::next_node() - { - if (!has_at_least_one_good_node()) - { - append_new_nodes(); - } - - if (m_nodes.empty()) - { - return {}; - } - - auto node = m_nodes.get().begin(); - const size_t count = std::distance(node, m_nodes.get().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().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().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(); - auto from = nodes_by_fails.rbegin(); - std::advance(from, total - m_max_nodes); - nodes_by_fails.erase(from.base(), nodes_by_fails.end()); - } - } - -} -} diff --git a/src/rpc/bootstrap_node_selector.h b/src/rpc/bootstrap_node_selector.h deleted file mode 100644 index 431e93db8..000000000 --- a/src/rpc/bootstrap_node_selector.h +++ /dev/null @@ -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 -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "net/http_client.h" - -namespace cryptonote -{ -namespace bootstrap_node -{ - - struct node_info - { - std::string address; - boost::optional credentials; - }; - - struct selector - { - virtual ~selector() = default; - - virtual void handle_result(const std::string &address, bool success) = 0; - virtual boost::optional next_node() = 0; - }; - - class selector_auto : public selector - { - public: - selector_auto(std::function()> 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 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::member>, - boost::multi_index::ordered_non_unique, boost::multi_index::member> - > - > nodes_list; - - const std::function()> m_get_nodes; - const size_t m_max_nodes; - nodes_list m_nodes; - }; - -} -} diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index a6885a659..9e66736c7 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -153,9 +153,6 @@ namespace cryptonote 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_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); command_line::add_arg(desc, arg_rpc_max_connections_per_public_ip); command_line::add_arg(desc, arg_rpc_max_connections_per_private_ip); @@ -169,79 +166,9 @@ namespace cryptonote ) : m_core(cr) , m_p2p(p2p) - , m_was_bootstrap_ever_used(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 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 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 result; - - const auto append = [&result](const std::vector &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 &credentials, - const std::string &proxy) - { - boost::unique_lock 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() { } @@ -253,7 +180,6 @@ namespace cryptonote , const std::string& proxy ) { - m_bootstrap_daemon_proxy = proxy; m_restricted = restricted; m_net_server.set_threads_prefix("RPC"); m_net_server.set_connection_filter(&m_p2p); @@ -277,15 +203,6 @@ namespace cryptonote disable_rpc_ban = rpc_config->disable_rpc_ban; 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 http_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) { RPC_TRACKER(get_height); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/getheight", req, res, r)) - return r; crypto::hash 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) { RPC_TRACKER(get_info); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/getinfo", req, res, r)) - { - { - boost::shared_lock 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; @@ -473,21 +371,6 @@ namespace cryptonote res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time(); res.free_space = restricted ? std::numeric_limits::max() : m_core.get_free_space(); 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 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(); if (restricted) 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) { 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(); { 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); - bool use_bootstrap_daemon; - { - boost::shared_lock 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(invoke_http_mode::BIN, "/getblocks.bin", req, res, r); - } - res.daemon_time = (uint64_t)time(NULL); // 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 @@ -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) { RPC_TRACKER(get_alt_blocks_hashes); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_alt_blocks_hashes", req, res, r)) - return r; std::vector 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) { RPC_TRACKER(get_blocks_by_height); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_hashes); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/gethashes.bin", req, res, r)) - return r; 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)) @@ -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) { RPC_TRACKER(get_outs_bin); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/get_outs.bin", req, res, r)) - return r; 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) { RPC_TRACKER(get_outs); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_outs", req, res, r)) - return r; 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) { RPC_TRACKER(get_indexes); - bool ok; - if (use_bootstrap_daemon_if_necessary(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); 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) { RPC_TRACKER(get_transactions); - bool ok; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/gettransactions", req, res, ok)) - return ok; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(is_key_image_spent); - bool ok; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok)) - return ok; const bool restricted = m_restricted && ctx; if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT) @@ -1226,30 +1074,7 @@ namespace cryptonote { RPC_TRACKER(send_raw_tx); - { - bool ok; - use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/sendrawtransaction", req, res, ok); - } - - const bool restricted = m_restricted && ctx; - - bool skip_validation = false; - if (!restricted) - { - boost::shared_lock lock(m_bootstrap_daemon_mutex); - if (m_should_use_bootstrap_daemon) - { - skip_validation = !check_core_ready(); - } - else - { - CHECK_CORE_READY(); - } - } - else - { - CHECK_CORE_READY(); - } + CHECK_CORE_READY(); std::string 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; - 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{}; - if(!m_core.handle_incoming_tx(tx_blob, tvc, (req.do_not_relay ? relay_method::none : relay_method::local), false) || tvc.m_verifivation_failed) + res.status = "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"; - 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; + 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; + } - if(tvc.m_relay == relay_method::none) - { - LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed"); - res.reason = "Not relayed"; - res.not_relayed = true; - res.status = CORE_RPC_STATUS_OK; - return true; - } + if(tvc.m_relay == relay_method::none) + { + LOG_PRINT_L0("[on_send_raw_tx]: tx accepted, but not relayed"); + res.reason = "Not relayed"; + res.not_relayed = true; + res.status = CORE_RPC_STATUS_OK; + return true; } 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) { RPC_TRACKER(get_transaction_pool); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_transaction_pool_hashes); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_hashes.bin", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_transaction_pool_hashes); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_hashes", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_transaction_pool_stats); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON, "/get_transaction_pool_stats", req, res, r)) - return r; const bool restricted = m_restricted && ctx; const bool request_has_rpc_origin = ctx != NULL; @@ -1660,28 +1470,6 @@ namespace cryptonote 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 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) { 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) { RPC_TRACKER(getblockcount); - { - boost::shared_lock 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.status = CORE_RPC_STATUS_OK; 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) { RPC_TRACKER(getblockhash); - { - boost::shared_lock 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) { 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) { RPC_TRACKER(getblocktemplate); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblocktemplate", req, res, r)) - return r; 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) { RPC_TRACKER(add_aux_pow); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "add_aux_pow", req, res, r)) - return r; 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) { RPC_TRACKER(submitblock); - { - boost::shared_lock 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(); if(req.size()!=1) { @@ -2313,103 +2073,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - template - 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 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 lock(upgrade_lock); - m_bootstrap_height_check_time = current_time; - } - - boost::optional> 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 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) { RPC_TRACKER(get_last_block_header); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getlastblockheader", req, res, r)) - return r; CHECK_CORE_READY(); 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) { RPC_TRACKER(get_block_header_by_hash); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblockheaderbyhash", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_block_headers_range); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblockheadersrange", req, res, r)) - return r; 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) @@ -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) { RPC_TRACKER(get_block_header_by_height); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblockheaderbyheight", req, res, r)) - return r; 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) { RPC_TRACKER(get_block); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "getblock", req, res, r)) - return r; crypto::hash block_hash; 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) { RPC_TRACKER(hard_fork_info); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "hard_fork_info", req, res, r)) - return r; const Blockchain &blockchain = m_core.get_blockchain_storage(); 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) { RPC_TRACKER(get_output_histogram); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_output_histogram", req, res, r)) - return r; const bool restricted = m_restricted && ctx; 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) { RPC_TRACKER(get_version); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_version", req, res, r)) - return r; res.version = CORE_RPC_VERSION; 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) { RPC_TRACKER(get_base_fee_estimate); - bool r; - if (use_bootstrap_daemon_if_necessary(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); @@ -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) { RPC_TRACKER(get_limit); - bool r; - if (use_bootstrap_daemon_if_necessary(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_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) { RPC_TRACKER(get_txpool_backlog); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_txpool_backlog", req, res, r)) - return r; 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) { RPC_TRACKER(get_output_distribution); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::JON_RPC, "get_output_distribution", req, res, r)) - return r; const bool restricted = m_restricted && ctx; if (restricted && req.amounts != std::vector(1, 0)) @@ -3323,10 +2956,6 @@ namespace cryptonote { RPC_TRACKER(get_output_distribution_bin); - bool r; - if (use_bootstrap_daemon_if_necessary(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r)) - return r; - const bool restricted = m_restricted && ctx; if (restricted && req.amounts != std::vector(1, 0)) { @@ -3405,9 +3034,6 @@ namespace cryptonote { 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 const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (m_restricted ? 1 : 10); @@ -3503,25 +3129,6 @@ namespace cryptonote , false }; - const command_line::arg_descriptor 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 core_rpc_server::arg_bootstrap_daemon_login = { - "bootstrap-daemon-login" - , "Specify username:password for the bootstrap daemon login" - , "" - }; - - const command_line::arg_descriptor core_rpc_server::arg_bootstrap_daemon_proxy = { - "bootstrap-daemon-proxy" - , ": socks proxy to use for bootstrap daemon connections" - , "" - }; - const command_line::arg_descriptor core_rpc_server::arg_rpc_max_connections_per_public_ip = { "rpc-max-connections-per-public-ip" , "Max RPC connections per public IP permitted" diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index f263101c8..590209314 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -35,7 +35,6 @@ #include #include -#include "bootstrap_daemon.h" #include "net/http_server_impl_base.h" #include "net/http_client.h" #include "core_rpc_server_commands_defs.h" @@ -64,9 +63,6 @@ namespace cryptonote static const command_line::arg_descriptor arg_rpc_ssl_ca_certificates; static const command_line::arg_descriptor> arg_rpc_ssl_allowed_fingerprints; static const command_line::arg_descriptor arg_rpc_ssl_allow_any_cert; - static const command_line::arg_descriptor arg_bootstrap_daemon_address; - static const command_line::arg_descriptor arg_bootstrap_daemon_login; - static const command_line::arg_descriptor arg_bootstrap_daemon_proxy; static const command_line::arg_descriptor arg_rpc_max_connections_per_public_ip; static const command_line::arg_descriptor arg_rpc_max_connections_per_private_ip; static const command_line::arg_descriptor 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", 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_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("/get_info", 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(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_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_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); @@ -258,28 +252,10 @@ private: //utils 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); - std::map 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 &credentials, - const std::string &proxy); - enum invoke_http_mode { JON, BIN, JON_RPC }; - template - 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); core& m_core; nodetool::node_server >& m_p2p; - boost::shared_mutex m_bootstrap_daemon_mutex; - std::unique_ptr 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; epee::critical_section m_host_fails_score_lock; std::map m_host_fails_score; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 7815964f6..edc00587e 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -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 // Don't go over 32767 for any of these #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 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 { std::string status; - bool untrusted; - - rpc_response_base(): untrusted(false) {} BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(status) - KV_SERIALIZE(untrusted) 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 free_space; bool offline; - std::string bootstrap_daemon_address; - uint64_t height_without_bootstrap; - bool was_bootstrap_ever_used; uint64_t database_size; bool update_available; 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(free_space) 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(update_available) 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; }; - 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; - - struct response_t - { - std::string status; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(status) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_STOP_DAEMON { struct request_t: public rpc_request_base diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 50c61d47b..bc1a7cc93 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -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("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")); - - 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()) diff --git a/tests/fuzz/fuzz_rpc/fuzz_rpc.cpp b/tests/fuzz/fuzz_rpc/fuzz_rpc.cpp index 92ffe9936..1f38da381 100644 --- a/tests/fuzz/fuzz_rpc/fuzz_rpc.cpp +++ b/tests/fuzz/fuzz_rpc/fuzz_rpc.cpp @@ -67,9 +67,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } - // Disable bootstrap daemon - disable_bootstrap_daemon(*rpc_handler->rpc); - for (unsigned selector : selectors) { try { // Fuzz the target function diff --git a/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp b/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp index b794e916d..2a4d6589a 100644 --- a/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp +++ b/tests/fuzz/fuzz_rpc/rpc_endpoints.cpp @@ -7,19 +7,6 @@ cryptonote::core_rpc_server::connection_context ctx; 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 std::map> get_fuzz_targets(bool safe) { std::map> 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); } -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) { cryptonote::COMMAND_RPC_STOP_DAEMON::request req; cryptonote::COMMAND_RPC_STOP_DAEMON::response res; @@ -865,7 +837,6 @@ std::map *performance_timers; } -void disable_bootstrap_daemon(cryptonote::core_rpc_server& rpc); std::map> get_fuzz_targets(bool safe); 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(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_get_info(cryptonote::core_rpc_server&, FuzzedDataProvider& provider); void fuzz_get_net_stats(cryptonote::core_rpc_server&, FuzzedDataProvider& provider); diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index dc30a241c..0aea4ffdf 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -34,7 +34,6 @@ set(unit_tests_sources blockchain_db.cpp block_queue.cpp block_reward.cpp - bootstrap_node_selector.cpp bulletproofs.cpp bulletproofs_plus.cpp canonical_amounts.cpp diff --git a/tests/unit_tests/bootstrap_node_selector.cpp b/tests/unit_tests/bootstrap_node_selector.cpp deleted file mode 100644 index 1ac9b915b..000000000 --- a/tests/unit_tests/bootstrap_node_selector.cpp +++ /dev/null @@ -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 - -#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 white_nodes = { - { - "white_node_1:18089", true - }, - { - "white_node_2:18081", true - } - }; - const std::map gray_nodes = { - { - "gray_node_1:18081", false - }, - { - "gray_node_2:18089", false - } - }; - - std::map nodes; -}; - -TEST_F(bootstrap_node_selector, selector_auto_empty) -{ - cryptonote::bootstrap_node::selector_auto selector([]() { - return std::map(); - }); - - 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(); - }, max_nodes); - - std::set 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); -} diff --git a/utils/fish/monerod.fish b/utils/fish/monerod.fish index c8d2b8c27..3b2b2b3e4 100644 --- a/utils/fish/monerod.fish +++ b/utils/fish/monerod.fish @@ -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-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 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 ": 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-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" diff --git a/utils/python-rpc/framework/daemon.py b/utils/python-rpc/framework/daemon.py index adab4204c..8dacc4083 100644 --- a/utils/python-rpc/framework/daemon.py +++ b/utils/python-rpc/framework/daemon.py @@ -329,14 +329,6 @@ class Daemon(object): } 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): get_public_nodes = { 'gray': gray,