mirror of
https://github.com/wownero/wownero.git
synced 2026-11-14 04:13:54 +01:00
Merge pull request #10694
a01b4c2 daemon: remove bootstrap mode (tobtoht)
ACKs: thomasbuilds, selsta
This commit is contained in:
+45
-438
@@ -154,9 +154,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);
|
||||
@@ -170,79 +167,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<epee::net_utils::http::login> credentials;
|
||||
const auto loc = username_password.find(':');
|
||||
if (loc != std::string::npos)
|
||||
{
|
||||
credentials = epee::net_utils::http::login(username_password.substr(0, loc), username_password.substr(loc + 1));
|
||||
}
|
||||
return set_bootstrap_daemon(address, credentials, proxy);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, bool> core_rpc_server::get_public_nodes(uint32_t/* = 0*/)
|
||||
{
|
||||
COMMAND_RPC_GET_PUBLIC_NODES::request request;
|
||||
COMMAND_RPC_GET_PUBLIC_NODES::response response;
|
||||
|
||||
request.gray = true;
|
||||
request.white = true;
|
||||
request.include_blocked = false;
|
||||
if (!on_get_public_nodes(request, response) || response.status != CORE_RPC_STATUS_OK)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::map<std::string, bool> result;
|
||||
|
||||
const auto append = [&result](const std::vector<public_node> &nodes, bool white) {
|
||||
for (const auto &node : nodes)
|
||||
{
|
||||
result.insert(std::make_pair(node.host + ":" + std::to_string(node.rpc_port), white));
|
||||
}
|
||||
};
|
||||
|
||||
append(response.white, true);
|
||||
append(response.gray, false);
|
||||
|
||||
return result;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const boost::optional<epee::net_utils::http::login> &credentials,
|
||||
const std::string &proxy)
|
||||
{
|
||||
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
|
||||
if (address.empty())
|
||||
{
|
||||
m_bootstrap_daemon.reset(nullptr);
|
||||
}
|
||||
else if (address == "auto")
|
||||
{
|
||||
auto get_nodes = [this]() {
|
||||
return get_public_nodes(0);
|
||||
};
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
||||
}
|
||||
|
||||
m_should_use_bootstrap_daemon = m_bootstrap_daemon.get() != nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
core_rpc_server::~core_rpc_server()
|
||||
{
|
||||
}
|
||||
@@ -254,7 +181,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);
|
||||
@@ -278,15 +204,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<epee::net_utils::http::login> http_login{};
|
||||
|
||||
if (rpc_config->login)
|
||||
@@ -409,9 +326,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<COMMAND_RPC_GET_HEIGHT>(invoke_http_mode::JON, "/getheight", req, res, r))
|
||||
return r;
|
||||
|
||||
crypto::hash hash;
|
||||
m_core.get_blockchain_top(res.height, hash);
|
||||
@@ -424,22 +338,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<COMMAND_RPC_GET_INFO>(invoke_http_mode::JON, "/getinfo", req, res, r))
|
||||
{
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_bootstrap_daemon.get() != nullptr)
|
||||
{
|
||||
res.bootstrap_daemon_address = m_bootstrap_daemon->address();
|
||||
}
|
||||
}
|
||||
crypto::hash top_hash;
|
||||
m_core.get_blockchain_top(res.height_without_bootstrap, top_hash);
|
||||
++res.height_without_bootstrap; // turn top block height into blockchain height
|
||||
res.was_bootstrap_ever_used = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
|
||||
@@ -474,21 +372,6 @@ namespace cryptonote
|
||||
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
|
||||
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
||||
res.offline = m_core.offline();
|
||||
res.height_without_bootstrap = restricted ? 0 : res.height;
|
||||
if (restricted)
|
||||
{
|
||||
res.bootstrap_daemon_address = "";
|
||||
res.was_bootstrap_ever_used = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_bootstrap_daemon.get() != nullptr)
|
||||
{
|
||||
res.bootstrap_daemon_address = m_bootstrap_daemon->address();
|
||||
}
|
||||
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
||||
}
|
||||
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
|
||||
if (restricted)
|
||||
res.database_size = round_up(res.database_size, 5ull* 1024 * 1024 * 1024);
|
||||
@@ -505,7 +388,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);
|
||||
@@ -608,17 +491,6 @@ namespace cryptonote
|
||||
{
|
||||
RPC_TRACKER(get_blocks);
|
||||
|
||||
bool use_bootstrap_daemon;
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
use_bootstrap_daemon = m_should_use_bootstrap_daemon;
|
||||
}
|
||||
if (use_bootstrap_daemon)
|
||||
{
|
||||
bool r;
|
||||
return use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_FAST>(invoke_http_mode::BIN, "/getblocks.bin", req, res, r);
|
||||
}
|
||||
|
||||
res.daemon_time = (uint64_t)time(NULL);
|
||||
// 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
|
||||
@@ -707,9 +579,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<COMMAND_RPC_GET_ALT_BLOCKS_HASHES>(invoke_http_mode::JON, "/get_alt_blocks_hashes", req, res, r))
|
||||
return r;
|
||||
|
||||
std::vector<block> blks;
|
||||
|
||||
@@ -734,9 +603,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<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
||||
@@ -775,9 +641,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<COMMAND_RPC_GET_HASHES_FAST>(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))
|
||||
@@ -794,9 +657,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<COMMAND_RPC_GET_OUTPUTS_BIN>(invoke_http_mode::BIN, "/get_outs.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
res.status = "Failed";
|
||||
|
||||
@@ -822,9 +682,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<COMMAND_RPC_GET_OUTPUTS>(invoke_http_mode::JON, "/get_outs", req, res, r))
|
||||
return r;
|
||||
|
||||
res.status = "Failed";
|
||||
|
||||
@@ -867,9 +724,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<COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES>(invoke_http_mode::BIN, "/get_o_indexes.bin", req, res, ok))
|
||||
return ok;
|
||||
|
||||
bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes);
|
||||
if(!r)
|
||||
@@ -885,9 +739,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<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
||||
return ok;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
@@ -1133,9 +984,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<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
||||
return ok;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
||||
@@ -1220,30 +1068,7 @@ namespace cryptonote
|
||||
{
|
||||
RPC_TRACKER(send_raw_tx);
|
||||
|
||||
{
|
||||
bool ok;
|
||||
use_bootstrap_daemon_if_necessary<COMMAND_RPC_SEND_RAW_TX>(invoke_http_mode::JON, "/sendrawtransaction", req, res, ok);
|
||||
}
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
|
||||
bool skip_validation = false;
|
||||
if (!restricted)
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_should_use_bootstrap_daemon)
|
||||
{
|
||||
skip_validation = !check_core_ready();
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_CORE_READY();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_CORE_READY();
|
||||
}
|
||||
CHECK_CORE_READY();
|
||||
|
||||
std::string tx_blob;
|
||||
if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob))
|
||||
@@ -1263,53 +1088,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;
|
||||
@@ -1573,9 +1395,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<COMMAND_RPC_GET_TRANSACTION_POOL>(invoke_http_mode::JON, "/get_transaction_pool", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
@@ -1596,9 +1415,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<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN>(invoke_http_mode::JON, "/get_transaction_pool_hashes.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
@@ -1617,9 +1433,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<COMMAND_RPC_GET_TRANSACTION_POOL_HASHES>(invoke_http_mode::JON, "/get_transaction_pool_hashes", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
@@ -1642,9 +1455,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<COMMAND_RPC_GET_TRANSACTION_POOL_STATS>(invoke_http_mode::JON, "/get_transaction_pool_stats", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
const bool request_has_rpc_origin = ctx != NULL;
|
||||
@@ -1654,28 +1464,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<epee::net_utils::http::login> credentials;
|
||||
if (!req.username.empty() || !req.password.empty())
|
||||
{
|
||||
credentials = epee::net_utils::http::login(req.username, req.password);
|
||||
}
|
||||
|
||||
if (set_bootstrap_daemon(req.address, credentials, req.proxy))
|
||||
{
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.status = "Failed to set bootstrap daemon";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx)
|
||||
{
|
||||
RPC_TRACKER(stop_daemon);
|
||||
@@ -1689,14 +1477,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<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_should_use_bootstrap_daemon)
|
||||
{
|
||||
res.status = "This command is unsupported for bootstrap daemon";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
res.count = m_core.get_current_blockchain_height();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
@@ -1705,14 +1486,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<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_should_use_bootstrap_daemon)
|
||||
{
|
||||
res = "This command is unsupported for bootstrap daemon";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(req.size() != 1)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
||||
@@ -1802,9 +1576,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<COMMAND_RPC_GETBLOCKTEMPLATE>(invoke_http_mode::JON_RPC, "getblocktemplate", req, res, r))
|
||||
return r;
|
||||
|
||||
if(!check_core_ready())
|
||||
{
|
||||
@@ -1996,9 +1767,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<COMMAND_RPC_ADD_AUX_POW>(invoke_http_mode::JON_RPC, "add_aux_pow", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
|
||||
@@ -2142,15 +1910,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<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
if (m_should_use_bootstrap_daemon)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_UNSUPPORTED_BOOTSTRAP;
|
||||
error_resp.message = "This command is unsupported for bootstrap daemon";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_CORE_READY();
|
||||
if(req.size()!=1)
|
||||
{
|
||||
@@ -2307,103 +2067,9 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
template <typename COMMAND_TYPE>
|
||||
bool core_rpc_server::use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r)
|
||||
{
|
||||
res.untrusted = false;
|
||||
r = false;
|
||||
|
||||
boost::upgrade_lock<boost::shared_mutex> upgrade_lock(m_bootstrap_daemon_mutex);
|
||||
|
||||
if (m_bootstrap_daemon.get() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_should_use_bootstrap_daemon)
|
||||
{
|
||||
MINFO("The local daemon is fully synced. Not switching back to the bootstrap daemon");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto current_time = std::chrono::system_clock::now();
|
||||
if (current_time - m_bootstrap_height_check_time > std::chrono::seconds(30)) // update every 30s
|
||||
{
|
||||
{
|
||||
boost::upgrade_to_unique_lock<boost::shared_mutex> lock(upgrade_lock);
|
||||
m_bootstrap_height_check_time = current_time;
|
||||
}
|
||||
|
||||
boost::optional<std::pair<uint64_t, uint64_t>> bootstrap_daemon_height_info = m_bootstrap_daemon->get_height();
|
||||
if (!bootstrap_daemon_height_info)
|
||||
{
|
||||
MERROR("Failed to fetch bootstrap daemon height");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t bootstrap_daemon_height = bootstrap_daemon_height_info->first;
|
||||
const uint64_t bootstrap_daemon_target_height = bootstrap_daemon_height_info->second;
|
||||
if (bootstrap_daemon_height < bootstrap_daemon_target_height)
|
||||
{
|
||||
MINFO("Bootstrap daemon is out of sync");
|
||||
return m_bootstrap_daemon->handle_result(false, {});
|
||||
}
|
||||
|
||||
if (bootstrap_daemon_height < m_core.get_checkpoints().get_max_height())
|
||||
{
|
||||
MINFO("Bootstrap daemon height is lower than the latest checkpoint");
|
||||
return m_bootstrap_daemon->handle_result(false, {});
|
||||
}
|
||||
|
||||
if (!m_p2p.get_payload_object().no_sync())
|
||||
{
|
||||
uint64_t top_height = m_core.get_current_blockchain_height();
|
||||
m_should_use_bootstrap_daemon = top_height + 10 < bootstrap_daemon_height;
|
||||
MINFO((m_should_use_bootstrap_daemon ? "Using" : "Not using") << " the bootstrap daemon (our height: " << top_height << ", bootstrap daemon's height: " << bootstrap_daemon_height << ")");
|
||||
|
||||
if (!m_should_use_bootstrap_daemon)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == invoke_http_mode::JON)
|
||||
{
|
||||
r = m_bootstrap_daemon->invoke_http_json(command_name, req, res);
|
||||
}
|
||||
else if (mode == invoke_http_mode::BIN)
|
||||
{
|
||||
r = m_bootstrap_daemon->invoke_http_bin(command_name, req, res);
|
||||
}
|
||||
else if (mode == invoke_http_mode::JON_RPC)
|
||||
{
|
||||
r = m_bootstrap_daemon->invoke_http_json_rpc(command_name, req, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
MERROR("Unknown invoke_http_mode: " << mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
boost::upgrade_to_unique_lock<boost::shared_mutex> lock(upgrade_lock);
|
||||
m_was_bootstrap_ever_used = true;
|
||||
}
|
||||
|
||||
if (r && res.status != CORE_RPC_STATUS_PAYMENT_REQUIRED && res.status != CORE_RPC_STATUS_OK)
|
||||
{
|
||||
MINFO("Failing RPC " << command_name << " due to peer return status " << res.status);
|
||||
r = false;
|
||||
}
|
||||
res.untrusted = true;
|
||||
return r;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
RPC_TRACKER(get_last_block_header);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_LAST_BLOCK_HEADER>(invoke_http_mode::JON_RPC, "getlastblockheader", req, res, r))
|
||||
return r;
|
||||
|
||||
CHECK_CORE_READY();
|
||||
uint64_t last_block_height;
|
||||
@@ -2432,9 +2098,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<COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH>(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)
|
||||
@@ -2499,9 +2162,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<COMMAND_RPC_GET_BLOCK_HEADERS_RANGE>(invoke_http_mode::JON_RPC, "getblockheadersrange", req, res, r))
|
||||
return r;
|
||||
|
||||
const uint64_t bc_height = m_core.get_current_blockchain_height();
|
||||
if (req.start_height >= bc_height || req.end_height >= bc_height || req.start_height > req.end_height)
|
||||
@@ -2558,9 +2218,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<COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT>(invoke_http_mode::JON_RPC, "getblockheaderbyheight", req, res, r))
|
||||
return r;
|
||||
|
||||
if(m_core.get_current_blockchain_height() <= req.height)
|
||||
{
|
||||
@@ -2592,9 +2249,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<COMMAND_RPC_GET_BLOCK>(invoke_http_mode::JON_RPC, "getblock", req, res, r))
|
||||
return r;
|
||||
|
||||
crypto::hash block_hash;
|
||||
if (!req.hash.empty())
|
||||
@@ -2677,9 +2331,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<COMMAND_RPC_HARD_FORK_INFO>(invoke_http_mode::JON_RPC, "hard_fork_info", req, res, r))
|
||||
return r;
|
||||
|
||||
const Blockchain &blockchain = m_core.get_blockchain_storage();
|
||||
uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version();
|
||||
@@ -2865,9 +2516,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<COMMAND_RPC_GET_OUTPUT_HISTOGRAM>(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();
|
||||
@@ -2909,9 +2557,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<COMMAND_RPC_GET_VERSION>(invoke_http_mode::JON_RPC, "get_version", req, res, r))
|
||||
return r;
|
||||
|
||||
res.version = CORE_RPC_VERSION;
|
||||
res.release = MONERO_VERSION_IS_RELEASE;
|
||||
@@ -2942,9 +2587,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<COMMAND_RPC_GET_BASE_FEE_ESTIMATE>(invoke_http_mode::JON_RPC, "get_fee_estimate", req, res, r))
|
||||
return r;
|
||||
|
||||
{
|
||||
m_core.get_blockchain_storage().get_dynamic_base_fee_estimate_2021_scaling(req.grace_blocks, res.fees);
|
||||
@@ -2991,9 +2633,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<COMMAND_RPC_GET_LIMIT>(invoke_http_mode::JON, "/get_limit", req, res, r))
|
||||
return r;
|
||||
|
||||
res.limit_down = epee::net_utils::connection_basic::get_rate_down_limit();
|
||||
res.limit_up = epee::net_utils::connection_basic::get_rate_up_limit();
|
||||
@@ -3255,9 +2894,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<COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG>(invoke_http_mode::JON_RPC, "get_txpool_backlog", req, res, r))
|
||||
return r;
|
||||
|
||||
if (!m_core.get_txpool_backlog(res.backlog))
|
||||
{
|
||||
@@ -3273,9 +2909,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<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(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<uint64_t>(1, 0))
|
||||
@@ -3317,10 +2950,6 @@ namespace cryptonote
|
||||
{
|
||||
RPC_TRACKER(get_output_distribution_bin);
|
||||
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
||||
{
|
||||
@@ -3399,9 +3028,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 bool restricted = m_restricted && ctx;
|
||||
const uint64_t max_num_txids = RESTRICTED_SPENT_KEY_IMAGES_COUNT * (restricted ? 1 : 10);
|
||||
@@ -3503,25 +3129,6 @@ namespace cryptonote
|
||||
, false
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_address = {
|
||||
"bootstrap-daemon-address"
|
||||
, "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n"
|
||||
"Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
|
||||
, ""
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_login = {
|
||||
"bootstrap-daemon-login"
|
||||
, "Specify username:password for the bootstrap daemon login"
|
||||
, ""
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_proxy = {
|
||||
"bootstrap-daemon-proxy"
|
||||
, "<ip>:<port> socks proxy to use for bootstrap daemon connections"
|
||||
, ""
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::size_t> core_rpc_server::arg_rpc_max_connections_per_public_ip = {
|
||||
"rpc-max-connections-per-public-ip"
|
||||
, "Max RPC connections per public IP permitted"
|
||||
|
||||
Reference in New Issue
Block a user