Merge pull request #5623
b8cfa92
rpc: implement set_bootstrap_daemon method (xiphon)
This commit is contained in:
commit
d4d5a4433d
|
@ -105,6 +105,35 @@ namespace cryptonote
|
||||||
, m_p2p(p2p)
|
, m_p2p(p2p)
|
||||||
{}
|
{}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, const std::string &username_password)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials)
|
||||||
|
{
|
||||||
|
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||||
|
|
||||||
|
if (!address.empty())
|
||||||
|
{
|
||||||
|
if (!m_http_client.set_server(address, credentials, epee::net_utils::ssl_support_t::e_ssl_support_autodetect))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bootstrap_daemon_address = address;
|
||||||
|
m_should_use_bootstrap_daemon = !m_bootstrap_daemon_address.empty();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool core_rpc_server::init(
|
bool core_rpc_server::init(
|
||||||
const boost::program_options::variables_map& vm
|
const boost::program_options::variables_map& vm
|
||||||
, const bool restricted
|
, const bool restricted
|
||||||
|
@ -118,29 +147,12 @@ namespace cryptonote
|
||||||
if (!rpc_config)
|
if (!rpc_config)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_bootstrap_daemon_address = command_line::get_arg(vm, arg_bootstrap_daemon_address);
|
if (!set_bootstrap_daemon(command_line::get_arg(vm, arg_bootstrap_daemon_address),
|
||||||
if (!m_bootstrap_daemon_address.empty())
|
command_line::get_arg(vm, arg_bootstrap_daemon_login)))
|
||||||
{
|
{
|
||||||
const std::string &bootstrap_daemon_login = command_line::get_arg(vm, arg_bootstrap_daemon_login);
|
MERROR("Failed to parse bootstrap daemon address");
|
||||||
const auto loc = bootstrap_daemon_login.find(':');
|
return false;
|
||||||
if (!bootstrap_daemon_login.empty() && loc != std::string::npos)
|
|
||||||
{
|
|
||||||
epee::net_utils::http::login login;
|
|
||||||
login.username = bootstrap_daemon_login.substr(0, loc);
|
|
||||||
login.password = bootstrap_daemon_login.substr(loc + 1);
|
|
||||||
m_http_client.set_server(m_bootstrap_daemon_address, login, epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_http_client.set_server(m_bootstrap_daemon_address, boost::none, epee::net_utils::ssl_support_t::e_ssl_support_autodetect);
|
|
||||||
}
|
|
||||||
m_should_use_bootstrap_daemon = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_should_use_bootstrap_daemon = false;
|
|
||||||
}
|
|
||||||
m_was_bootstrap_ever_used = false;
|
|
||||||
|
|
||||||
boost::optional<epee::net_utils::http::login> http_login{};
|
boost::optional<epee::net_utils::http::login> http_login{};
|
||||||
|
|
||||||
|
@ -185,7 +197,10 @@ namespace cryptonote
|
||||||
bool r;
|
bool r;
|
||||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_INFO>(invoke_http_mode::JON, "/getinfo", req, res, 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);
|
||||||
res.bootstrap_daemon_address = m_bootstrap_daemon_address;
|
res.bootstrap_daemon_address = m_bootstrap_daemon_address;
|
||||||
|
}
|
||||||
crypto::hash top_hash;
|
crypto::hash top_hash;
|
||||||
m_core.get_blockchain_top(res.height_without_bootstrap, 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.height_without_bootstrap; // turn top block height into blockchain height
|
||||||
|
@ -224,13 +239,16 @@ namespace cryptonote
|
||||||
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
|
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
|
||||||
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
||||||
res.offline = m_core.offline();
|
res.offline = m_core.offline();
|
||||||
res.bootstrap_daemon_address = restricted ? "" : m_bootstrap_daemon_address;
|
|
||||||
res.height_without_bootstrap = restricted ? 0 : res.height;
|
res.height_without_bootstrap = restricted ? 0 : res.height;
|
||||||
if (restricted)
|
if (restricted)
|
||||||
|
{
|
||||||
|
res.bootstrap_daemon_address = "";
|
||||||
res.was_bootstrap_ever_used = false;
|
res.was_bootstrap_ever_used = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||||
|
res.bootstrap_daemon_address = m_bootstrap_daemon_address;
|
||||||
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
||||||
}
|
}
|
||||||
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
|
res.database_size = m_core.get_blockchain_storage().get_db().get_database_size();
|
||||||
|
@ -1125,6 +1143,28 @@ namespace cryptonote
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool core_rpc_server::on_set_bootstrap_daemon(const COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request& req, COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response& res, const connection_context *ctx)
|
||||||
|
{
|
||||||
|
PERF_TIMER(on_set_bootstrap_daemon);
|
||||||
|
|
||||||
|
boost::optional<epee::net_utils::http::login> credentials;
|
||||||
|
if (!req.username.empty() || !req.password.empty())
|
||||||
|
{
|
||||||
|
credentials = epee::net_utils::http::login(req.username, req.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_bootstrap_daemon(req.address, credentials))
|
||||||
|
{
|
||||||
|
res.status = CORE_RPC_STATUS_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.status = "Failed to set bootstrap daemon";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx)
|
bool core_rpc_server::on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx)
|
||||||
{
|
{
|
||||||
PERF_TIMER(on_stop_daemon);
|
PERF_TIMER(on_stop_daemon);
|
||||||
|
@ -1449,10 +1489,12 @@ namespace cryptonote
|
||||||
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)
|
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;
|
res.untrusted = false;
|
||||||
|
|
||||||
|
boost::upgrade_lock<boost::shared_mutex> upgrade_lock(m_bootstrap_daemon_mutex);
|
||||||
|
|
||||||
if (m_bootstrap_daemon_address.empty())
|
if (m_bootstrap_daemon_address.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
|
||||||
if (!m_should_use_bootstrap_daemon)
|
if (!m_should_use_bootstrap_daemon)
|
||||||
{
|
{
|
||||||
MINFO("The local daemon is fully synced. Not switching back to the bootstrap daemon");
|
MINFO("The local daemon is fully synced. Not switching back to the bootstrap daemon");
|
||||||
|
@ -1462,7 +1504,10 @@ namespace cryptonote
|
||||||
auto current_time = std::chrono::system_clock::now();
|
auto current_time = std::chrono::system_clock::now();
|
||||||
if (current_time - m_bootstrap_height_check_time > std::chrono::seconds(30)) // update every 30s
|
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;
|
m_bootstrap_height_check_time = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t top_height;
|
uint64_t top_height;
|
||||||
crypto::hash top_hash;
|
crypto::hash top_hash;
|
||||||
|
@ -1506,7 +1551,12 @@ namespace cryptonote
|
||||||
MERROR("Unknown invoke_http_mode: " << mode);
|
MERROR("Unknown invoke_http_mode: " << mode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::upgrade_to_unique_lock<boost::shared_mutex> lock(upgrade_lock);
|
||||||
m_was_bootstrap_ever_used = true;
|
m_was_bootstrap_ever_used = true;
|
||||||
|
}
|
||||||
|
|
||||||
r = r && res.status == CORE_RPC_STATUS_OK;
|
r = r && res.status == CORE_RPC_STATUS_OK;
|
||||||
res.untrusted = true;
|
res.untrusted = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace cryptonote
|
||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes.bin", on_get_transaction_pool_hashes_bin, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes.bin", on_get_transaction_pool_hashes_bin, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN)
|
||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes", on_get_transaction_pool_hashes, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_hashes", on_get_transaction_pool_hashes, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES)
|
||||||
MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS)
|
MAP_URI_AUTO_JON2("/get_transaction_pool_stats", on_get_transaction_pool_stats, COMMAND_RPC_GET_TRANSACTION_POOL_STATS)
|
||||||
|
MAP_URI_AUTO_JON2_IF("/set_bootstrap_daemon", on_set_bootstrap_daemon, COMMAND_RPC_SET_BOOTSTRAP_DAEMON, !m_restricted)
|
||||||
MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted)
|
MAP_URI_AUTO_JON2_IF("/stop_daemon", on_stop_daemon, COMMAND_RPC_STOP_DAEMON, !m_restricted)
|
||||||
MAP_URI_AUTO_JON2("/get_info", on_get_info, COMMAND_RPC_GET_INFO)
|
MAP_URI_AUTO_JON2("/get_info", on_get_info, COMMAND_RPC_GET_INFO)
|
||||||
MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO)
|
MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO)
|
||||||
|
@ -192,6 +193,7 @@ namespace cryptonote
|
||||||
bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_hashes_bin(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES_BIN::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_hashes(const COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_HASHES::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx = NULL);
|
bool on_get_transaction_pool_stats(const COMMAND_RPC_GET_TRANSACTION_POOL_STATS::request& req, COMMAND_RPC_GET_TRANSACTION_POOL_STATS::response& res, const connection_context *ctx = NULL);
|
||||||
|
bool on_set_bootstrap_daemon(const COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request& req, COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx = NULL);
|
bool on_stop_daemon(const COMMAND_RPC_STOP_DAEMON::request& req, COMMAND_RPC_STOP_DAEMON::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx = NULL);
|
bool on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res, const connection_context *ctx = NULL);
|
||||||
bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx = NULL);
|
bool on_set_limit(const COMMAND_RPC_SET_LIMIT::request& req, COMMAND_RPC_SET_LIMIT::response& res, const connection_context *ctx = NULL);
|
||||||
|
@ -238,6 +240,8 @@ private:
|
||||||
//utils
|
//utils
|
||||||
uint64_t get_block_reward(const block& blk);
|
uint64_t get_block_reward(const block& blk);
|
||||||
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash);
|
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash);
|
||||||
|
bool set_bootstrap_daemon(const std::string &address, const std::string &username_password);
|
||||||
|
bool set_bootstrap_daemon(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials);
|
||||||
enum invoke_http_mode { JON, BIN, JON_RPC };
|
enum invoke_http_mode { JON, BIN, JON_RPC };
|
||||||
template <typename COMMAND_TYPE>
|
template <typename COMMAND_TYPE>
|
||||||
bool use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r);
|
bool 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);
|
||||||
|
|
|
@ -1586,6 +1586,33 @@ namespace cryptonote
|
||||||
typedef epee::misc_utils::struct_init<response_t> response;
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct COMMAND_RPC_SET_BOOTSTRAP_DAEMON
|
||||||
|
{
|
||||||
|
struct request_t
|
||||||
|
{
|
||||||
|
std::string address;
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE(address)
|
||||||
|
KV_SERIALIZE(username)
|
||||||
|
KV_SERIALIZE(password)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<request_t> request;
|
||||||
|
|
||||||
|
struct response_t
|
||||||
|
{
|
||||||
|
std::string status;
|
||||||
|
|
||||||
|
BEGIN_KV_SERIALIZE_MAP()
|
||||||
|
KV_SERIALIZE(status)
|
||||||
|
END_KV_SERIALIZE_MAP()
|
||||||
|
};
|
||||||
|
typedef epee::misc_utils::struct_init<response_t> response;
|
||||||
|
};
|
||||||
|
|
||||||
struct COMMAND_RPC_STOP_DAEMON
|
struct COMMAND_RPC_STOP_DAEMON
|
||||||
{
|
{
|
||||||
struct request_t
|
struct request_t
|
||||||
|
|
Loading…
Reference in New Issue