delete bootstrap daemon

This commit is contained in:
Sean Darcy 2021-11-11 14:35:17 +11:00
parent 285e89ecda
commit cf8ecd2d17
13 changed files with 7 additions and 539 deletions

View File

@ -850,18 +850,6 @@ bool command_parser_executor::check_blockchain_pruning(const std::vector<std::st
return m_executor.check_blockchain_pruning();
}
bool command_parser_executor::set_bootstrap_daemon(const std::vector<std::string>& args)
{
const size_t args_count = args.size();
if (args_count < 1 || args_count > 3)
return false;
return m_executor.set_bootstrap_daemon(
args[0] != "none" ? args[0] : std::string(),
args_count > 1 ? args[1] : std::string(),
args_count > 2 ? args[2] : std::string());
}
bool command_parser_executor::flush_cache(const std::vector<std::string>& args)
{
bool bad_txs = false, bad_blocks = false;

View File

@ -142,8 +142,6 @@ public:
bool print_sn_state_changes(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);
void test_trigger_uptime_proof() { m_executor.test_trigger_uptime_proof(); }

View File

@ -324,12 +324,6 @@ or "default" to return the limit to its default value.)"
, "print_sn_state_changes <start_height> [end height]"
, "Query the state changes between the range, omit the last argument to scan until the current block"
);
m_command_lookup.set_handler(
"set_bootstrap_daemon"
, [this](const auto &x) { return m_parser.set_bootstrap_daemon(x); }
, "set_bootstrap_daemon (auto | none | host[:port] [username] [password])"
, "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced."
);
m_command_lookup.set_handler(
"flush_cache"
, [this](const auto &x) { return m_parser.flush_cache(x); }

View File

@ -44,7 +44,6 @@
#include "rpc/rpc_args.h"
#include "rpc/http_server.h"
#include "rpc/lmq_server.h"
#include "rpc/bootstrap_daemon.h"
#include "cryptonote_protocol/quorumnet.h"
#include "cryptonote_core/uptime_proof.h"

View File

@ -492,7 +492,6 @@ bool rpc_command_executor::show_status() {
uint64_t height = info["height"].get<uint64_t>();
uint64_t net_height = std::max(info["target_height"].get<uint64_t>(), height);
std::string bootstrap_msg;
std::ostringstream str;
str << "Height: " << height;
@ -506,17 +505,6 @@ bool rpc_command_executor::show_status() {
if (height < net_height)
str << ", syncing";
if (info.value("was_bootstrap_ever_used", false))
{
str << ", bootstrap " << info["bootstrap_daemon_address"].get<std::string_view>();
if (info.value("untrusted", false)) {
auto hwb = info["height_without_bootstrap"].get<uint64_t>();
str << fmt::format(", local height: {} ({:.1f}%)", hwb, get_sync_percentage(hwb, net_height));
}
else
str << " was used";
}
auto hf_version = hfinfo["version"].get<uint8_t>();
if (hf_version < HF_VERSION_PULSE && !has_mining_info)
str << ", mining info unavailable";
@ -1222,12 +1210,12 @@ bool rpc_command_executor::output_histogram(const std::vector<uint64_t> &amounts
if (!invoke<GET_OUTPUT_HISTOGRAM>(std::move(req), res, "Failed to retrieve output histogram"))
return false;
std::sort(res.histogram.begin(), res.histogram.end(),
[](const auto& e1, const auto& e2)->bool { return e1.total_instances < e2.total_instances; });
for (const auto &e: res.histogram)
{
tools::msg_writer() << e.total_instances << " " << cryptonote::print_money(e.amount);
}
//std::sort(res.histogram.begin(), res.histogram.end(),
//[](const auto& e1, const auto& e2)->bool { return e1.total_instances < e2.total_instances; });
//for (const auto &e: res.histogram)
//{
//tools::msg_writer() << e.total_instances << " " << cryptonote::print_money(e.amount);
//}
return true;
}
@ -2489,26 +2477,6 @@ bool rpc_command_executor::check_blockchain_pruning()
return true;
}
bool rpc_command_executor::set_bootstrap_daemon(
const std::string &address,
const std::string &username,
const std::string &password)
{
SET_BOOTSTRAP_DAEMON::request req{};
req.address = address;
req.username = username;
req.password = password;
SET_BOOTSTRAP_DAEMON::response res{};
if (!invoke<SET_BOOTSTRAP_DAEMON>(std::move(req), res, "Failed to set bootstrap daemon to: " + address))
return false;
tools::success_msg_writer()
<< "Successfully set bootstrap daemon address to "
<< (!req.address.empty() ? req.address : "none");
return true;
}
bool rpc_command_executor::version()
{
auto version = try_running([this] {

View File

@ -239,11 +239,6 @@ public:
bool print_net_stats();
bool set_bootstrap_daemon(
const std::string &address,
const std::string &username,
const std::string &password);
bool flush_cache(bool bad_txs, bool invalid_blocks);
bool version();

View File

@ -40,7 +40,6 @@ add_library(rpc_server_base
)
add_library(rpc
bootstrap_daemon.cpp
core_rpc_server.cpp
)

View File

@ -1,86 +0,0 @@
#include "bootstrap_daemon.h"
#include <stdexcept>
#include "common/string_util.h"
#include "crypto/crypto.h"
#include "cryptonote_core/cryptonote_core.h"
#include "epee/misc_log_ex.h"
#undef OXEN_DEFAULT_LOG_CATEGORY
#define OXEN_DEFAULT_LOG_CATEGORY "daemon.rpc.bootstrap_daemon"
namespace cryptonote
{
bootstrap_daemon::bootstrap_daemon(std::function<std::optional<std::string>()> get_next_public_node)
: m_get_next_public_node(get_next_public_node)
{
}
bootstrap_daemon::bootstrap_daemon(const std::string &address, const std::optional<std::pair<std::string_view, std::string_view>> &credentials)
: bootstrap_daemon(nullptr)
{
if (!set_server(address, credentials))
{
throw std::runtime_error("invalid bootstrap daemon address or credentials");
}
}
std::string bootstrap_daemon::address() const noexcept
{
return m_http_client.get_base_url();
}
std::optional<uint64_t> bootstrap_daemon::get_height()
{
// FIXME
throw std::runtime_error{"FIXME"};
/*
// query bootstrap daemon's height
rpc::GET_HEIGHT::response res{};
if (!invoke<rpc::GET_HEIGHT>({}, res))
{
return std::nullopt;
}
if (res.status != cryptonote::rpc::STATUS_OK)
{
return std::nullopt;
}
return res.height;
*/
}
bool bootstrap_daemon::set_server(std::string url, const std::optional<std::pair<std::string_view, std::string_view>> &credentials /* = std::nullopt */)
{
if (!tools::starts_with(url, "http://") && !tools::starts_with(url, "https://"))
url.insert(0, "http://");
m_http_client.set_base_url(std::move(url));
if (credentials)
m_http_client.set_auth(credentials->first, credentials->second);
else
m_http_client.set_auth();
MINFO("Changed bootstrap daemon address to " << url);
return true;
}
bool bootstrap_daemon::switch_server_if_needed()
{
if (!m_failed || !m_get_next_public_node)
return true;
const std::optional<std::string> address = m_get_next_public_node();
if (address) {
m_failed = false;
return set_server(*address);
}
return false;
}
}

View File

@ -1,54 +0,0 @@
#pragma once
#include <functional>
#include <vector>
#include "rpc/http_client.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "rpc/core_rpc_server_binary_commands.h"
namespace cryptonote
{
class bootstrap_daemon
{
public:
bootstrap_daemon(std::function<std::optional<std::string>()> get_next_public_node);
bootstrap_daemon(const std::string &address, const std::optional<std::pair<std::string_view, std::string_view>> &credentials);
std::string address() const noexcept;
std::optional<uint64_t> get_height();
// Called when a request has failed either internally or for some external reason; the next
// request will attempt to use a different bootstrap server (if configured).
void set_failed() { m_failed = true; }
template <class RPC, std::enable_if_t<std::is_base_of_v<rpc::RPC_COMMAND, RPC>, int> = 0>
bool invoke(const typename RPC::request& req, typename RPC::response& res)
{
if (!switch_server_if_needed())
return false;
try {
if constexpr (std::is_base_of_v<rpc::BINARY, RPC>)
res = m_http_client.binary<RPC>(RPC::names().front(), req);
else
res = m_http_client.json_rpc<RPC>(RPC::names().front(), req);
} catch (const std::exception& e) {
MWARNING("bootstrap daemon request failed: " << e.what());
set_failed();
return false;
}
return true;
}
private:
bool set_server(std::string address, const std::optional<std::pair<std::string_view, std::string_view>> &credentials = std::nullopt);
bool switch_server_if_needed();
private:
rpc::http_client m_http_client;
std::function<std::optional<std::string>()> m_get_next_public_node;
bool m_failed = false;
};
}

View File

@ -46,14 +46,12 @@
#include "epee/net/network_throttle.hpp"
#include "oxen_economy.h"
#include "epee/string_tools.h"
#include "bootstrap_daemon.h"
#include "core_rpc_server.h"
#include "core_rpc_server_binary_commands.h"
#include "core_rpc_server_command_parser.h"
#include "core_rpc_server_error_codes.h"
#include "rpc_args.h"
#include "common/command_line.h"
#include "bootstrap_daemon.h"
#include "common/oxen.h"
#include "common/sha256sum.h"
#include "common/perf_timer.h"
@ -203,18 +201,6 @@ namespace cryptonote::rpc {
const std::unordered_map<std::string, std::shared_ptr<const rpc_command>> rpc_commands = register_rpc_commands(rpc::core_rpc_types{}, rpc::core_rpc_binary_types{});
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."
, ""
};
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"
, ""
};
std::optional<std::string_view> rpc_request::body_view() const {
if (auto* sv = std::get_if<std::string_view>(&body)) return *sv;
if (auto* s = std::get_if<std::string>(&body)) return *s;
@ -224,8 +210,6 @@ namespace cryptonote::rpc {
//-----------------------------------------------------------------------------------
void core_rpc_server::init_options(boost::program_options::options_description& desc, boost::program_options::options_description& hidden)
{
command_line::add_arg(desc, arg_bootstrap_daemon_address);
command_line::add_arg(desc, arg_bootstrap_daemon_login);
cryptonote::rpc_args::init_options(desc, hidden);
}
//------------------------------------------------------------------------------------------------------------------------------
@ -235,47 +219,7 @@ namespace cryptonote::rpc {
)
: m_core(cr)
, m_p2p(p2p)
, m_should_use_bootstrap_daemon(false)
, m_was_bootstrap_ever_used(false)
{}
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, std::string_view username_password)
{
std::string_view username, password;
if (auto loc = username_password.find(':'); loc != std::string::npos)
{
username = username_password.substr(0, loc);
password = username_password.substr(loc + 1);
}
return set_bootstrap_daemon(address, username, password);
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, std::string_view username, std::string_view password)
{
std::optional<std::pair<std::string_view, std::string_view>> credentials;
if (!username.empty() || !password.empty())
credentials.emplace(username, password);
std::unique_lock lock{m_bootstrap_daemon_mutex};
if (address.empty())
m_bootstrap_daemon.reset();
else
m_bootstrap_daemon = std::make_unique<bootstrap_daemon>(address, credentials);
m_should_use_bootstrap_daemon = (bool) m_bootstrap_daemon;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
void core_rpc_server::init(const boost::program_options::variables_map& vm)
{
if (!set_bootstrap_daemon(command_line::get_arg(vm, arg_bootstrap_daemon_address),
command_line::get_arg(vm, arg_bootstrap_daemon_login)))
{
MERROR("Failed to parse bootstrap daemon address");
}
m_was_bootstrap_ever_used = false;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::check_core_ready()
{
@ -289,11 +233,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_HEIGHT& get_height, rpc_context context)
{
PERF_TIMER(on_get_height);
/* FIXME
if (use_bootstrap_daemon_if_necessary<GET_HEIGHT>(req, res))
return res;
*/
auto [height, hash] = m_core.get_blockchain_top();
++height; // block height to chain height
@ -313,27 +252,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_INFO& info, rpc_context context)
{
PERF_TIMER(on_get_info);
/*
* FIXME
*
if (use_bootstrap_daemon_if_necessary<GET_INFO>(req, res))
{
if (context.admin)
{
crypto::hash top_hash;
m_core.get_blockchain_top(res.height_without_bootstrap.emplace(), top_hash);
++*res.height_without_bootstrap; // turn top block height into blockchain height
res.was_bootstrap_ever_used = true;
std::shared_lock lock{m_bootstrap_daemon_mutex};
if (m_bootstrap_daemon.get() != nullptr)
{
res.bootstrap_daemon_address = m_bootstrap_daemon->address();
}
}
return res;
}
*/
auto [top_height, top_hash] = m_core.get_blockchain_top();
@ -420,12 +338,6 @@ namespace cryptonote::rpc {
info.response["last_lokinet_ping"] = m_core.m_last_lokinet_ping.load();
}
info.response["free_space"] = m_core.get_free_space();
if (std::shared_lock lock{m_bootstrap_daemon_mutex}; m_bootstrap_daemon) {
info.response["bootstrap_daemon_address"] = m_bootstrap_daemon->address();
info.response["height_without_bootstrap"] = height;
info.response["was_bootstrap_ever_used"] = m_was_bootstrap_ever_used;
}
}
if (m_core.offline())
@ -442,7 +354,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_NET_STATS& get_net_stats, rpc_context context)
{
PERF_TIMER(on_get_net_stats);
// No bootstrap daemon check: Only ever get stats about local server
get_net_stats.response["start_time"] = m_core.get_start_time();
{
std::lock_guard lock{epee::net_utils::network_throttle_manager::m_lock_get_global_throttle_in};
@ -475,9 +386,6 @@ namespace cryptonote::rpc {
GET_BLOCKS_BIN::response res{};
PERF_TIMER(on_get_blocks);
if (use_bootstrap_daemon_if_necessary<GET_BLOCKS_BIN>(req, res))
return res;
std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > > bs;
if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, !req.no_miner_tx, GET_BLOCKS_BIN::MAX_COUNT))
@ -530,9 +438,6 @@ namespace cryptonote::rpc {
GET_ALT_BLOCKS_HASHES_BIN::response res{};
PERF_TIMER(on_get_alt_blocks_hashes);
if (use_bootstrap_daemon_if_necessary<GET_ALT_BLOCKS_HASHES_BIN>(req, res))
return res;
std::vector<block> blks;
if(!m_core.get_alternative_blocks(blks))
@ -558,8 +463,6 @@ namespace cryptonote::rpc {
GET_BLOCKS_BY_HEIGHT_BIN::response res{};
PERF_TIMER(on_get_blocks_by_height);
if (use_bootstrap_daemon_if_necessary<GET_BLOCKS_BY_HEIGHT_BIN>(req, res))
return res;
res.status = "Failed";
res.blocks.clear();
@ -592,8 +495,6 @@ namespace cryptonote::rpc {
GET_HASHES_BIN::response res{};
PERF_TIMER(on_get_hashes);
if (use_bootstrap_daemon_if_necessary<GET_HASHES_BIN>(req, res))
return res;
res.start_height = req.start_height;
if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, res.m_block_ids, res.start_height, res.current_height, false))
@ -611,8 +512,6 @@ namespace cryptonote::rpc {
GET_OUTPUTS_BIN::response res{};
PERF_TIMER(on_get_outs_bin);
if (use_bootstrap_daemon_if_necessary<GET_OUTPUTS_BIN>(req, res))
return res;
if (!context.admin && req.outputs.size() > GET_OUTPUTS_BIN::MAX_COUNT)
res.status = "Too many outs requested";
@ -627,10 +526,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_OUTPUTS& get_outputs, rpc_context context)
{
PERF_TIMER(on_get_outs);
//TODO this bootstrap daemon call to work for new RPC design
//if (use_bootstrap_daemon_if_necessary<GET_OUTPUTS>(req, res))
//return;
if (!context.admin && get_outputs.request.output_indices.size() > GET_OUTPUTS::MAX_COUNT) {
get_outputs.response["status"] = "Too many outs requested";
return;
@ -685,9 +580,6 @@ namespace cryptonote::rpc {
GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN::response res{};
PERF_TIMER(on_get_indexes);
if (use_bootstrap_daemon_if_necessary<GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN>(req, res))
return res;
bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes);
if(!r)
{
@ -930,11 +822,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_TRANSACTIONS& get, rpc_context context)
{
PERF_TIMER(on_get_transactions);
/*
if (use_bootstrap_daemon_if_necessary<GET_TRANSACTIONS>(req, res))
return res;
*/
std::unordered_set<crypto::hash> missed_txs;
using split_tx = std::tuple<crypto::hash, std::string, crypto::hash, std::string>;
std::vector<split_tx> txs;
@ -1144,11 +1031,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(IS_KEY_IMAGE_SPENT& spent, rpc_context context)
{
PERF_TIMER(on_is_key_image_spent);
/*
if (use_bootstrap_daemon_if_necessary<IS_KEY_IMAGE_SPENT>(req, res))
return res;
*/
spent.response["status"] = STATUS_FAILED;
std::vector<bool> blockchain_spent;
@ -1180,11 +1062,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(SUBMIT_TRANSACTION& tx, rpc_context context)
{
PERF_TIMER(on_submit_transaction);
/*
if (use_bootstrap_daemon_if_necessary<SUBMIT_TRANSACTION>(req, res))
return res;
*/
if (!check_core_ready()) {
tx.response["status"] = STATUS_BUSY;
return;
@ -1409,9 +1286,6 @@ namespace cryptonote::rpc {
GET_TRANSACTION_POOL_HASHES_BIN::response res{};
PERF_TIMER(on_get_transaction_pool_hashes);
if (use_bootstrap_daemon_if_necessary<GET_TRANSACTION_POOL_HASHES_BIN>(req, res))
return res;
std::vector<crypto::hash> tx_pool_hashes;
m_core.get_pool().get_transaction_hashes(tx_pool_hashes, context.admin, req.blinked_txs_only);
@ -1423,10 +1297,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_TRANSACTION_POOL_HASHES& get_transaction_pool_hashes, rpc_context context)
{
PERF_TIMER(on_get_transaction_pool_hashes);
//TODO handle bootstrap daemon with RPC
//if (use_bootstrap_daemon_if_necessary<GET_TRANSACTION_POOL_HASHES>(req, res))
//return res;
std::vector<crypto::hash> tx_hashes;
m_core.get_pool().get_transaction_hashes(tx_hashes, context.admin);
get_transaction_pool_hashes.response_hex["tx_hashes"] = tx_hashes;
@ -1436,10 +1306,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_TRANSACTION_POOL_STATS& stats, rpc_context context)
{
PERF_TIMER(on_get_transaction_pool_stats);
//TODO handle bootstrap daemon
//if (use_bootstrap_daemon_if_necessary<GET_TRANSACTION_POOL_STATS>(req, res))
//return res;
auto txpool = m_core.get_pool().get_transaction_stats(stats.request.include_unrelayed);
json pool_stats{
{"bytes_total", txpool.bytes_total},
@ -1464,18 +1330,6 @@ namespace cryptonote::rpc {
stats.response["status"] = STATUS_OK;
}
//------------------------------------------------------------------------------------------------------------------------------
SET_BOOTSTRAP_DAEMON::response core_rpc_server::invoke(SET_BOOTSTRAP_DAEMON::request&& req, rpc_context context)
{
PERF_TIMER(on_set_bootstrap_daemon);
if (!set_bootstrap_daemon(req.address, req.username, req.password))
throw rpc_error{ERROR_WRONG_PARAM, "Failed to set bootstrap daemon to address = " + req.address};
SET_BOOTSTRAP_DAEMON::response res{};
res.status = STATUS_OK;
return res;
}
//------------------------------------------------------------------------------------------------------------------------------
void core_rpc_server::invoke(STOP_DAEMON& stop_daemon, rpc_context context)
{
PERF_TIMER(on_stop_daemon);
@ -1492,10 +1346,6 @@ namespace cryptonote::rpc {
GET_OUTPUT_BLACKLIST_BIN::response res{};
PERF_TIMER(on_get_output_blacklist_bin);
if (use_bootstrap_daemon_if_necessary<GET_OUTPUT_BLACKLIST_BIN>(req, res))
return res;
try
{
m_core.get_output_blacklist(res.blacklist);
@ -1513,14 +1363,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_BLOCK_COUNT& get, rpc_context context)
{
PERF_TIMER(on_getblockcount);
{
std::shared_lock lock{m_bootstrap_daemon_mutex};
if (m_should_use_bootstrap_daemon)
{
get.response["status"] = "This command is unsupported for bootstrap daemon";
return;
}
}
get.response["count"] = m_core.get_current_blockchain_height();
get.response["status"] = STATUS_OK;
}
@ -1528,15 +1370,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_BLOCK_HASH& get, rpc_context context)
{
PERF_TIMER(on_getblockhash);
{
std::shared_lock lock{m_bootstrap_daemon_mutex};
if (m_should_use_bootstrap_daemon)
{
get.response["status"] = "This command is unsupported for bootstrap daemon";
return;
}
}
auto curr_height = m_core.get_current_blockchain_height();
for (auto h : get.request.heights) {
if (h >= curr_height)
@ -1590,84 +1423,6 @@ namespace cryptonote::rpc {
}
}
/// All the common (untemplated) code for use_bootstrap_daemon_if_necessary. Returns a held lock
/// if we need to bootstrap, an unheld one if we don't.
std::unique_lock<std::shared_mutex> core_rpc_server::should_bootstrap_lock()
{
// TODO - support bootstrapping via a remote LMQ RPC; requires some argument fiddling
if (!m_should_use_bootstrap_daemon)
return {};
std::unique_lock lock{m_bootstrap_daemon_mutex};
if (!m_bootstrap_daemon)
{
lock.unlock();
return lock;
}
auto current_time = std::chrono::system_clock::now();
if (!m_p2p.get_payload_object().no_sync() &&
current_time - m_bootstrap_height_check_time > 30s) // update every 30s
{
m_bootstrap_height_check_time = current_time;
std::optional<uint64_t> bootstrap_daemon_height = m_bootstrap_daemon->get_height();
if (!bootstrap_daemon_height)
{
MERROR("Failed to fetch bootstrap daemon height");
lock.unlock();
return lock;
}
uint64_t target_height = m_core.get_target_blockchain_height();
if (bootstrap_daemon_height < target_height)
{
MINFO("Bootstrap daemon is out of sync");
lock.unlock();
m_bootstrap_daemon->set_failed();
return lock;
}
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)
{
MINFO("The local daemon is fully synced; disabling bootstrap daemon requests");
lock.unlock();
}
return lock;
}
//------------------------------------------------------------------------------------------------------------------------------
// If we have a bootstrap daemon configured and we haven't fully synched yet then forward the
// request to the bootstrap daemon. Returns true if the request was bootstrapped, false if the
// request shouldn't be bootstrapped, and throws an exception if the bootstrap request fails.
//
// The RPC type must have a `bool untrusted` member.
//
template <typename RPC>
bool core_rpc_server::use_bootstrap_daemon_if_necessary(const typename RPC::request& req, typename RPC::response& res)
{
res.untrusted = false; // If compilation fails here then the type being instantiated doesn't support using a bootstrap daemon
auto bs_lock = should_bootstrap_lock();
if (!bs_lock)
return false;
std::string command_name{RPC::names().front()};
if (!m_bootstrap_daemon->invoke<RPC>(req, res))
throw std::runtime_error{"Bootstrap request failed"};
m_was_bootstrap_ever_used = true;
res.untrusted = true;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
void core_rpc_server::invoke(GET_LAST_BLOCK_HEADER& get_last_block_header, rpc_context context)
{
@ -1875,10 +1630,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(HARD_FORK_INFO& hfinfo, rpc_context context)
{
PERF_TIMER(on_hard_fork_info);
/*
if (use_bootstrap_daemon_if_necessary<HARD_FORK_INFO>(req, res))
return res;
*/
const auto& blockchain = m_core.get_blockchain_storage();
uint8_t version =
@ -2045,8 +1796,6 @@ namespace cryptonote::rpc {
GET_OUTPUT_HISTOGRAM::response res{};
PERF_TIMER(on_get_output_histogram);
if (use_bootstrap_daemon_if_necessary<GET_OUTPUT_HISTOGRAM>(req, res))
return res;
if (!context.admin && req.recent_cutoff > 0 && req.recent_cutoff < (uint64_t)time(NULL) - OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION)
{
@ -2080,10 +1829,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_VERSION& version, rpc_context context)
{
PERF_TIMER(on_get_version);
//TODO how replace bootstrap daemon
//if (use_bootstrap_daemon_if_necessary<GET_VERSION>(req, res))
//return res;
version.response["version"] = pack_version(VERSION);
version.response["status"] = STATUS_OK;
}
@ -2134,10 +1879,6 @@ namespace cryptonote::rpc {
void core_rpc_server::invoke(GET_BASE_FEE_ESTIMATE& get_base_fee_estimate, rpc_context context)
{
PERF_TIMER(on_get_base_fee_estimate);
//TODO handle bootstrap daemon in new RPC format
//if (use_bootstrap_daemon_if_necessary<GET_BASE_FEE_ESTIMATE>(req, res))
//return res;
auto fees = m_core.get_blockchain_storage().get_dynamic_base_fee_estimate(get_base_fee_estimate.request.grace_blocks);
get_base_fee_estimate.response["fee_per_byte"] = fees.first;
get_base_fee_estimate.response["fee_per_output"] = fees.second;
@ -2430,9 +2171,6 @@ namespace cryptonote::rpc {
GET_OUTPUT_DISTRIBUTION::response res{};
PERF_TIMER(on_get_output_distribution);
if (use_bootstrap_daemon_if_necessary<GET_OUTPUT_DISTRIBUTION>(req, res))
return res;
try
{
// 0 is placeholder for the whole chain
@ -2477,9 +2215,6 @@ namespace cryptonote::rpc {
return res;
}
if (use_bootstrap_daemon_if_necessary<GET_OUTPUT_DISTRIBUTION_BIN>(req, res))
return res;
return invoke(std::move(static_cast<GET_OUTPUT_DISTRIBUTION::request&>(req)), context, true);
}
//------------------------------------------------------------------------------------------------------------------------------

View File

@ -51,10 +51,6 @@ namespace boost::program_options {
class variables_map;
}
namespace cryptonote {
class bootstrap_daemon;
}
namespace cryptonote::rpc {
// FIXME: temporary shim for converting RPC methods
@ -183,8 +179,6 @@ namespace cryptonote::rpc {
class core_rpc_server
{
public:
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_address;
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_login;
core_rpc_server(
core& cr
@ -192,7 +186,6 @@ namespace cryptonote::rpc {
);
static void init_options(boost::program_options::options_description& desc, boost::program_options::options_description& hidden);
void init(const boost::program_options::variables_map& vm);
/// Returns a reference to the owning cryptonote core object
core& get_core() { return m_core; }
@ -271,7 +264,6 @@ namespace cryptonote::rpc {
GET_OUTPUT_DISTRIBUTION::response invoke(GET_OUTPUT_DISTRIBUTION::request&& req, rpc_context context, bool binary = false);
// FIXME: unconverted JSON RPC endpoints:
SET_BOOTSTRAP_DAEMON::response invoke(SET_BOOTSTRAP_DAEMON::request&& req, rpc_context context);
GET_OUTPUT_HISTOGRAM::response invoke(GET_OUTPUT_HISTOGRAM::request&& req, rpc_context context);
GET_ALTERNATE_CHAINS::response invoke(GET_ALTERNATE_CHAINS::request&& req, rpc_context context);
GET_QUORUM_STATE::response invoke(GET_QUORUM_STATE::request&& req, rpc_context context);
@ -292,21 +284,11 @@ private:
//utils
uint64_t get_block_reward(const block& blk);
bool set_bootstrap_daemon(const std::string &address, std::string_view username_password);
bool set_bootstrap_daemon(const std::string &address, std::string_view username, std::string_view password);
void 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 get_tx_hashes);
std::unique_lock<std::shared_mutex> should_bootstrap_lock();
template <typename COMMAND_TYPE>
bool use_bootstrap_daemon_if_necessary(const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res);
core& m_core;
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
std::shared_mutex m_bootstrap_daemon_mutex;
std::atomic<bool> m_should_use_bootstrap_daemon;
std::unique_ptr<bootstrap_daemon> m_bootstrap_daemon;
std::chrono::system_clock::time_point m_bootstrap_height_check_time;
bool m_was_bootstrap_ever_used;
};
} // namespace cryptonote::rpc

View File

@ -102,13 +102,6 @@ KV_SERIALIZE_MAP_CODE_BEGIN(block_header_response)
KV_SERIALIZE(service_node_winner)
KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(SET_BOOTSTRAP_DAEMON::request)
KV_SERIALIZE(address)
KV_SERIALIZE(username)
KV_SERIALIZE(password)
KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_HISTOGRAM::request)
KV_SERIALIZE(amounts);
KV_SERIALIZE(min_count);
@ -118,6 +111,7 @@ KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_HISTOGRAM::request)
KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_HISTOGRAM::entry)
KV_SERIALIZE(amount);
KV_SERIALIZE(total_instances);
@ -129,7 +123,6 @@ KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_HISTOGRAM::response)
KV_SERIALIZE(status)
KV_SERIALIZE(histogram)
KV_SERIALIZE(untrusted)
KV_SERIALIZE_MAP_CODE_END()
@ -222,7 +215,6 @@ KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_DISTRIBUTION::response)
KV_SERIALIZE(status)
KV_SERIALIZE(distributions)
KV_SERIALIZE(untrusted)
KV_SERIALIZE_MAP_CODE_END()
@ -249,7 +241,6 @@ KV_SERIALIZE_MAP_CODE_END()
KV_SERIALIZE_MAP_CODE_BEGIN(GET_QUORUM_STATE::response)
KV_SERIALIZE(status)
KV_SERIALIZE(quorums)
KV_SERIALIZE(untrusted)
KV_SERIALIZE_MAP_CODE_END()

View File

@ -209,7 +209,6 @@ namespace cryptonote::rpc {
///
/// - \p height -- The current blockchain height according to the queried daemon.
/// - \p status -- Generic RPC error code. "OK" is the success value.
/// - \p untrusted -- If the result is obtained using bootstrap mode then this will be set to
/// true, otherwise will be omitted.
/// - \p hash -- Hash of the block at the current height
/// - \p immutable_height -- The latest height in the blockchain that cannot be reorganized
@ -225,7 +224,6 @@ namespace cryptonote::rpc {
/// Outputs:
///
/// - \p status -- Generic RPC error code. "OK" is the success value.
/// - \p untrusted -- If the result is obtained using bootstrap mode then this will be set to
/// true, otherwise will be omitted.
/// - \p missed_tx -- set of transaction hashes that were not found. If all were found then this
/// field is omitted. There is no particular ordering of hashes in this list.
@ -401,7 +399,6 @@ namespace cryptonote::rpc {
/// Outputs
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore
/// untrusted ('true'), or when the daemon is fully synced ('false').
/// - \p spent_status array of status codes returned in the same order as the `key_images` input.
/// Each value is one of:
@ -437,7 +434,6 @@ namespace cryptonote::rpc {
/// Output values available from a public RPC endpoint:
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore
/// untrusted ('true'), or when the daemon is fully synced ('false').
/// - \p outs List of outkey information; if `as_tuple` is not set then these are dicts containing
/// keys:
@ -477,7 +473,6 @@ namespace cryptonote::rpc {
/// Output values available from a public RPC endpoint:
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore
/// untrusted ('true'), or when the daemon is fully synced ('false').
/// - \p reason String containing additional information on why a transaction failed.
/// - \p blink_status Set to the result of submitting this transaction to the Blink quorum. 1
@ -522,7 +517,6 @@ namespace cryptonote::rpc {
// std::string status; // General RPC error code. "OK" means everything looks good. Any other value means that something went wrong.
// std::string reason; // Additional information. Currently empty, "Not relayed" if transaction was accepted but not relayed, or some descriptive message of why the tx failed.
// bool not_relayed; // Transaction was not relayed (true) or relayed (false).
// bool untrusted; // States if the result is obtained using the bootstrap mode, and is therefore not trusted (`true`), or when the daemon is fully synced (`false`).
// tx_verification_context tvc;
// bool sanity_check_failed;
// blink_result blink_status; // 0 for a non-blink tx. For a blink tx: 1 means rejected, 2 means accepted, 3 means timeout.
@ -633,7 +627,6 @@ namespace cryptonote::rpc {
/// - \p block_size_median Median block size of latest 100 blocks.
/// - \p ons_counts ONS registration counts, as a three-element list: [session, wallet, lokinet]
/// - \p offline Indicates that the node is offline, if true. Omitted for online nodes.
/// - \p untrusted Indicates that the result was obtained using a bootstrap mode, and is therefore
/// not trusted (`true`). Omitted for non-bootstrap responses.
/// - \p database_size Current size of Blockchain data. Over public RPC this is rounded up to the
/// next-largest GB value.
@ -658,12 +651,6 @@ namespace cryptonote::rpc {
/// as a service node)
/// - \p last_lokinet_ping Last ping time of lokinet (0 if never or not running as a service node)
/// - \p free_space Available disk space on the node.
/// - \p bootstrap_daemon_address Bootstrap node to give immediate usability to wallets while
/// syncing by proxying RPC to it. (Note: the replies may be untrustworthy).
/// - \p height_without_bootstrap Current length of the local chain of the daemon. Only included
/// if a bootstrap daemon is configured.
/// - \p was_bootstrap_ever_used States if the bootstrap node has ever been used since the daemon
/// started. Omitted if no bootstrap node is configured.
struct GET_INFO : PUBLIC, LEGACY, NO_ARGS
{
static constexpr auto names() { return NAMES("get_info", "getinfo"); }
@ -971,7 +958,6 @@ namespace cryptonote::rpc {
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p tx_hashes List of transaction hashes,
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore not
/// trusted (`true`), or when the daemon is fully synced (`false`).
struct GET_TRANSACTION_POOL_HASHES : PUBLIC, LEGACY, NO_ARGS
{
@ -1015,7 +1001,6 @@ namespace cryptonote::rpc {
/// `histo_98pc`.
/// - \p histo_98pc See `histo` for details.
/// - \p histo_max See `histo` for details.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore not
/// trusted (`true`), or when the daemon is fully synced (`false`).
struct GET_TRANSACTION_POOL_STATS : PUBLIC, LEGACY
{
@ -1097,24 +1082,6 @@ namespace cryptonote::rpc {
} request;
};
OXEN_RPC_DOC_INTROSPECT
// Set the bootstrap daemon to use for data on the blockchain whilst syncing the chain.
struct SET_BOOTSTRAP_DAEMON : RPC_COMMAND
{
static constexpr auto names() { return NAMES("set_bootstrap_daemon"); }
struct request
{
std::string address;
std::string username;
std::string password;
KV_MAP_SERIALIZABLE
};
struct response : STATUS {};
};
//-----------------------------------------------
/// Stop the daemon.
///
@ -1213,7 +1180,6 @@ namespace cryptonote::rpc {
/// Output values available from a public RPC endpoint:
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore
/// untrusted ('true'), or when the daemon is fully synced ('false').
/// - \p version The major block version for the fork.
/// - \p enabled Indicates whether the hard fork is enforced on the blockchain (that is, whether
@ -1355,7 +1321,6 @@ namespace cryptonote::rpc {
{
std::string status; // General RPC error code. "OK" means everything looks good.
std::vector<entry> histogram; // List of histogram entries:
bool untrusted; // States if the result is obtained using the bootstrap mode, and is therefore not trusted (`true`), or when the daemon is fully synced (`false`).
KV_MAP_SERIALIZABLE
};
@ -1369,7 +1334,6 @@ namespace cryptonote::rpc {
///
/// - \p status General RPC status string. `"OK"` means everything looks good.
/// - \p version RPC current version.
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore not
/// trusted (`true`), or when the daemon is fully synced
struct GET_VERSION : PUBLIC, NO_ARGS
{
@ -1423,7 +1387,6 @@ namespace cryptonote::rpc {
/// - \p blink_fee_fixed Fixed blink fee in addition to the per-output and per-byte amounts. The
/// portion of the overall blink fee above the overall base fee is burned.
/// - \p quantization_mask
/// - \p untrusted States if the result is obtained using the bootstrap mode, and is therefore not
/// trusted (`true`), or when the daemon is fully synced (`false`).
struct GET_BASE_FEE_ESTIMATE : PUBLIC
{
@ -1556,7 +1519,6 @@ namespace cryptonote::rpc {
{
std::string status; // General RPC error code. "OK" means everything looks good.
std::vector<distribution> distributions; //
bool untrusted; // States if the result is obtained using the bootstrap mode, and is therefore not trusted (`true`), or when the daemon is fully synced (`false`).
KV_MAP_SERIALIZABLE
};
@ -1658,7 +1620,6 @@ namespace cryptonote::rpc {
{
std::string status; // Generic RPC error code. "OK" is the success value.
std::vector<quorum_for_height> quorums; // An array of quorums associated with the requested height
bool untrusted; // If the result is obtained using bootstrap mode, and therefore not trusted `true`, or otherwise `false`.
KV_MAP_SERIALIZABLE
};
@ -2122,7 +2083,6 @@ namespace cryptonote::rpc {
/// Output values available from a public RPC endpoint:
///
/// - \p status Generic RPC error code. "OK" is the success value.
/// - \p untrusted If the result is obtained using bootstrap mode then this will be set to true,
/// otherwise will be omitted.
/// - \p total_deregister
/// - \p total_ip_change_penalty
@ -2403,7 +2363,6 @@ namespace cryptonote::rpc {
GET_BLOCK_HEADER_BY_HEIGHT,
GET_BLOCK,
GET_BLOCK_HEADERS_RANGE,
SET_BOOTSTRAP_DAEMON,
GETBANS,
SETBANS,
GET_OUTPUT_HISTOGRAM,