mirror of
https://github.com/monero-project/monero.git
synced 2024-11-18 00:37:43 +00:00
Bootstrap daemon
This commit is contained in:
parent
ed67e5c001
commit
7539603f94
4 changed files with 370 additions and 5 deletions
|
@ -353,15 +353,18 @@ static std::string get_fork_extra_info(uint64_t t, uint64_t now, uint64_t block_
|
|||
return "";
|
||||
}
|
||||
|
||||
static float get_sync_percentage(const cryptonote::COMMAND_RPC_GET_INFO::response &ires)
|
||||
static float get_sync_percentage(uint64_t height, uint64_t target_height)
|
||||
{
|
||||
uint64_t height = ires.height;
|
||||
uint64_t target_height = ires.target_height ? ires.target_height < ires.height ? ires.height : ires.target_height : ires.height;
|
||||
target_height = target_height ? target_height < height ? height : target_height : height;
|
||||
float pc = 100.0f * height / target_height;
|
||||
if (height < target_height && pc > 99.9f)
|
||||
return 99.9f; // to avoid 100% when not fully synced
|
||||
return pc;
|
||||
}
|
||||
static float get_sync_percentage(const cryptonote::COMMAND_RPC_GET_INFO::response &ires)
|
||||
{
|
||||
return get_sync_percentage(ires.height, ires.target_height);
|
||||
}
|
||||
|
||||
bool t_rpc_command_executor::show_status() {
|
||||
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
|
||||
|
@ -421,12 +424,26 @@ bool t_rpc_command_executor::show_status() {
|
|||
|
||||
std::time_t uptime = std::time(nullptr) - ires.start_time;
|
||||
uint64_t net_height = ires.target_height > ires.height ? ires.target_height : ires.height;
|
||||
std::string bootstrap_msg;
|
||||
if (ires.was_bootstrap_ever_used)
|
||||
{
|
||||
bootstrap_msg = ", bootstrapping from " + ires.bootstrap_daemon_address;
|
||||
if (ires.untrusted)
|
||||
{
|
||||
bootstrap_msg += (boost::format(", local height: %llu (%.1f%%)") % ires.height_without_bootstrap % get_sync_percentage(ires.height_without_bootstrap, net_height)).str();
|
||||
}
|
||||
else
|
||||
{
|
||||
bootstrap_msg += " was used before";
|
||||
}
|
||||
}
|
||||
|
||||
tools::success_msg_writer() << boost::format("Height: %llu/%llu (%.1f%%) on %s, %s, net hash %s, v%u%s, %s, %u(out)+%u(in) connections, uptime %ud %uh %um %us")
|
||||
tools::success_msg_writer() << boost::format("Height: %llu/%llu (%.1f%%) on %s%s, %s, net hash %s, v%u%s, %s, %u(out)+%u(in) connections, uptime %ud %uh %um %us")
|
||||
% (unsigned long long)ires.height
|
||||
% (unsigned long long)net_height
|
||||
% get_sync_percentage(ires)
|
||||
% (ires.testnet ? "testnet" : "mainnet")
|
||||
% bootstrap_msg
|
||||
% (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed) ) : "not mining")
|
||||
% get_mining_speed(ires.difficulty / ires.target)
|
||||
% (unsigned)hfres.version
|
||||
|
|
|
@ -42,6 +42,7 @@ using namespace epee;
|
|||
#include "cryptonote_basic/account.h"
|
||||
#include "cryptonote_basic/cryptonote_basic_impl.h"
|
||||
#include "misc_language.h"
|
||||
#include "storages/http_abstract_invoke.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "rpc/rpc_args.h"
|
||||
#include "core_rpc_server_error_codes.h"
|
||||
|
@ -75,6 +76,8 @@ namespace cryptonote
|
|||
command_line::add_arg(desc, arg_testnet_rpc_bind_port);
|
||||
command_line::add_arg(desc, arg_testnet_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);
|
||||
cryptonote::rpc_args::init_options(desc);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -101,6 +104,30 @@ namespace cryptonote
|
|||
if (!rpc_config)
|
||||
return false;
|
||||
|
||||
m_bootstrap_daemon_address = command_line::get_arg(vm, arg_bootstrap_daemon_address);
|
||||
if (!m_bootstrap_daemon_address.empty())
|
||||
{
|
||||
const std::string &bootstrap_daemon_login = command_line::get_arg(vm, arg_bootstrap_daemon_login);
|
||||
const auto loc = bootstrap_daemon_login.find(':');
|
||||
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, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_http_client.set_server(m_bootstrap_daemon_address, boost::none, false);
|
||||
}
|
||||
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{};
|
||||
|
||||
if (rpc_config->login)
|
||||
|
@ -126,6 +153,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_height);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_HEIGHT>(invoke_http_mode::JON, "/getheight", req, res, r))
|
||||
return r;
|
||||
|
||||
res.height = m_core.get_current_blockchain_height();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -134,6 +165,17 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_info);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_INFO>(invoke_http_mode::JON, "/getinfo", req, res, r))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
crypto::hash top_hash;
|
||||
m_core.get_blockchain_top(res.height, top_hash);
|
||||
++res.height; // turn top block height into blockchain height
|
||||
|
@ -158,6 +200,12 @@ namespace cryptonote
|
|||
res.start_time = (uint64_t)m_core.get_start_time();
|
||||
res.free_space = m_restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
||||
res.offline = m_core.offline();
|
||||
res.bootstrap_daemon_address = m_bootstrap_daemon_address;
|
||||
res.height_without_bootstrap = res.height;
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -181,6 +229,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_blocks);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_FAST>(invoke_http_mode::BIN, "/getblocks.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > > bs;
|
||||
|
||||
if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
|
||||
|
@ -240,6 +292,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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::list<block> blks;
|
||||
|
||||
if(!m_core.get_alternative_blocks(blks))
|
||||
|
@ -263,6 +319,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
res.status = "Failed";
|
||||
res.blocks.clear();
|
||||
res.blocks.reserve(req.heights.size());
|
||||
|
@ -293,6 +353,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_hashes(const COMMAND_RPC_GET_HASHES_FAST::request& req, COMMAND_RPC_GET_HASHES_FAST::response& res)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
NOTIFY_RESPONSE_CHAIN_ENTRY::request resp;
|
||||
|
||||
resp.start_height = req.start_height;
|
||||
|
@ -312,6 +376,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_random_outs);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS>(invoke_http_mode::BIN, "/getrandom_outs.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
res.status = "Failed";
|
||||
|
||||
if (m_restricted)
|
||||
|
@ -351,6 +419,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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";
|
||||
|
||||
if (m_restricted)
|
||||
|
@ -374,6 +446,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_outs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res)
|
||||
{
|
||||
PERF_TIMER(on_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";
|
||||
|
||||
if (m_restricted)
|
||||
|
@ -412,6 +488,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_random_rct_outs(const COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::request& req, COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_random_rct_outs);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_RANDOM_RCT_OUTPUTS>(invoke_http_mode::BIN, "/getrandom_rctouts.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
res.status = "Failed";
|
||||
if(!m_core.get_random_rct_outs(req, res))
|
||||
{
|
||||
|
@ -436,6 +516,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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)
|
||||
{
|
||||
|
@ -450,6 +534,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res)
|
||||
{
|
||||
PERF_TIMER(on_get_transactions);
|
||||
bool ok;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
||||
return ok;
|
||||
|
||||
std::vector<crypto::hash> vh;
|
||||
for(const auto& tx_hex_str: req.txs_hashes)
|
||||
{
|
||||
|
@ -600,6 +688,10 @@ 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, bool request_has_rpc_origin)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
std::vector<crypto::key_image> key_images;
|
||||
for(const auto& ki_hex_str: req.key_images)
|
||||
{
|
||||
|
@ -663,6 +755,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res)
|
||||
{
|
||||
PERF_TIMER(on_send_raw_tx);
|
||||
bool ok;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_SEND_RAW_TX>(invoke_http_mode::JON, "/sendrawtransaction", req, res, ok))
|
||||
return ok;
|
||||
|
||||
CHECK_CORE_READY();
|
||||
|
||||
std::string tx_blob;
|
||||
|
@ -886,6 +982,10 @@ 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, bool request_has_rpc_origin)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_restricted);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -894,6 +994,10 @@ 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, bool request_has_rpc_origin)
|
||||
{
|
||||
PERF_TIMER(on_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.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
m_core.get_pool_transaction_hashes(res.tx_hashes, !request_has_rpc_origin || !m_restricted);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -902,6 +1006,10 @@ 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, bool request_has_rpc_origin)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
m_core.get_pool_transaction_stats(res.pool_stats, !request_has_rpc_origin || !m_restricted);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -920,6 +1028,14 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res)
|
||||
{
|
||||
PERF_TIMER(on_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 false;
|
||||
}
|
||||
}
|
||||
res.count = m_core.get_current_blockchain_height();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -928,6 +1044,14 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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 false;
|
||||
}
|
||||
}
|
||||
if(req.size() != 1)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
||||
|
@ -964,6 +1088,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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())
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;
|
||||
|
@ -1039,6 +1167,14 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_submitblock);
|
||||
{
|
||||
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 false;
|
||||
}
|
||||
}
|
||||
CHECK_CORE_READY();
|
||||
if(req.size()!=1)
|
||||
{
|
||||
|
@ -1112,9 +1248,80 @@ 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;
|
||||
if (m_bootstrap_daemon_address.empty())
|
||||
return false;
|
||||
|
||||
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
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
|
||||
{
|
||||
m_bootstrap_height_check_time = current_time;
|
||||
|
||||
uint64_t top_height;
|
||||
crypto::hash top_hash;
|
||||
m_core.get_blockchain_top(top_height, top_hash);
|
||||
++top_height; // turn top block height into blockchain height
|
||||
|
||||
// query bootstrap daemon's height
|
||||
cryptonote::COMMAND_RPC_GET_HEIGHT::request getheight_req;
|
||||
cryptonote::COMMAND_RPC_GET_HEIGHT::response getheight_res;
|
||||
bool ok = epee::net_utils::invoke_http_json("/getheight", getheight_req, getheight_res, m_http_client);
|
||||
ok = ok && getheight_res.status == CORE_RPC_STATUS_OK;
|
||||
|
||||
m_should_use_bootstrap_daemon = ok && top_height + 10 < getheight_res.height;
|
||||
MINFO((m_should_use_bootstrap_daemon ? "Using" : "Not using") << " the bootstrap daemon (our height: " << top_height << ", bootstrap daemon's height: " << getheight_res.height << ")");
|
||||
}
|
||||
if (!m_should_use_bootstrap_daemon)
|
||||
return false;
|
||||
|
||||
if (mode == invoke_http_mode::JON)
|
||||
{
|
||||
r = epee::net_utils::invoke_http_json(command_name, req, res, m_http_client);
|
||||
}
|
||||
else if (mode == invoke_http_mode::BIN)
|
||||
{
|
||||
r = epee::net_utils::invoke_http_bin(command_name, req, res, m_http_client);
|
||||
}
|
||||
else if (mode == invoke_http_mode::JON_RPC)
|
||||
{
|
||||
epee::json_rpc::request<typename COMMAND_TYPE::request> json_req = AUTO_VAL_INIT(json_req);
|
||||
epee::json_rpc::response<typename COMMAND_TYPE::response, std::string> json_resp = AUTO_VAL_INIT(json_resp);
|
||||
json_req.jsonrpc = "2.0";
|
||||
json_req.id = epee::serialization::storage_entry(0);
|
||||
json_req.method = command_name;
|
||||
json_req.params = req;
|
||||
r = net_utils::invoke_http_json("/json_rpc", json_req, json_resp, m_http_client);
|
||||
if (r)
|
||||
res = json_resp.result;
|
||||
}
|
||||
else
|
||||
{
|
||||
MERROR("Unknown invoke_http_mode: " << mode);
|
||||
return false;
|
||||
}
|
||||
m_was_bootstrap_ever_used = true;
|
||||
r = r && res.status == CORE_RPC_STATUS_OK;
|
||||
res.untrusted = true;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
crypto::hash last_block_hash;
|
||||
|
@ -1140,6 +1347,10 @@ 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){
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
crypto::hash block_hash;
|
||||
bool hash_parsed = parse_hash256(req.hash, block_hash);
|
||||
if(!hash_parsed)
|
||||
|
@ -1177,6 +1388,10 @@ 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){
|
||||
PERF_TIMER(on_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)
|
||||
{
|
||||
|
@ -1223,6 +1438,10 @@ 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){
|
||||
PERF_TIMER(on_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)
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
|
||||
|
@ -1251,6 +1470,10 @@ 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){
|
||||
PERF_TIMER(on_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())
|
||||
{
|
||||
|
@ -1320,6 +1543,16 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp)
|
||||
{
|
||||
PERF_TIMER(on_get_info_json);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_INFO>(invoke_http_mode::JON_RPC, "get_info", req, res, r))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
crypto::hash top_hash;
|
||||
m_core.get_blockchain_top(res.height, top_hash);
|
||||
|
@ -1345,12 +1578,21 @@ namespace cryptonote
|
|||
res.start_time = (uint64_t)m_core.get_start_time();
|
||||
res.free_space = m_restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
|
||||
res.offline = m_core.offline();
|
||||
res.bootstrap_daemon_address = m_bootstrap_daemon_address;
|
||||
res.height_without_bootstrap = res.height;
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
res.was_bootstrap_ever_used = m_was_bootstrap_ever_used;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
PERF_TIMER(on_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();
|
||||
|
@ -1473,6 +1715,9 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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;
|
||||
|
||||
std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> histogram;
|
||||
try
|
||||
|
@ -1500,6 +1745,10 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -1518,6 +1767,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_per_kb_fee_estimate(const COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request& req, COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response& res, epee::json_rpc::error& error_resp)
|
||||
{
|
||||
PERF_TIMER(on_get_per_kb_fee_estimate);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE>(invoke_http_mode::JON_RPC, "get_fee_estimate", req, res, r))
|
||||
return r;
|
||||
|
||||
res.fee = m_core.get_blockchain_storage().get_dynamic_per_kb_fee_estimate(req.grace_blocks);
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
|
@ -1545,6 +1798,10 @@ namespace cryptonote
|
|||
bool core_rpc_server::on_get_limit(const COMMAND_RPC_GET_LIMIT::request& req, COMMAND_RPC_GET_LIMIT::response& res)
|
||||
{
|
||||
PERF_TIMER(on_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();
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
|
@ -1790,6 +2047,9 @@ 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)
|
||||
{
|
||||
PERF_TIMER(on_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))
|
||||
{
|
||||
|
@ -1832,4 +2092,16 @@ namespace cryptonote
|
|||
, "Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls"
|
||||
, 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"
|
||||
, ""
|
||||
};
|
||||
|
||||
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"
|
||||
, ""
|
||||
};
|
||||
} // namespace cryptonote
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
#include "net/http_server_impl_base.h"
|
||||
#include "net/http_client.h"
|
||||
#include "core_rpc_server_commands_defs.h"
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "p2p/net_node.h"
|
||||
|
@ -57,6 +58,8 @@ namespace cryptonote
|
|||
static const command_line::arg_descriptor<std::string> arg_testnet_rpc_bind_port;
|
||||
static const command_line::arg_descriptor<std::string> arg_testnet_rpc_restricted_bind_port;
|
||||
static const command_line::arg_descriptor<bool> arg_restricted_rpc;
|
||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_address;
|
||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_login;
|
||||
|
||||
typedef epee::net_utils::connection_context_base connection_context;
|
||||
|
||||
|
@ -220,9 +223,18 @@ private:
|
|||
//utils
|
||||
uint64_t get_block_reward(const block& blk);
|
||||
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response);
|
||||
enum invoke_http_mode { JON, BIN, JON_RPC };
|
||||
template <typename COMMAND_TYPE>
|
||||
bool use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r);
|
||||
|
||||
core& m_core;
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
||||
std::string m_bootstrap_daemon_address;
|
||||
epee::net_utils::http::http_simple_client m_http_client;
|
||||
boost::shared_mutex m_bootstrap_daemon_mutex;
|
||||
bool m_should_use_bootstrap_daemon;
|
||||
std::chrono::system_clock::time_point m_bootstrap_height_check_time;
|
||||
bool m_was_bootstrap_ever_used;
|
||||
bool m_testnet;
|
||||
bool m_restricted;
|
||||
};
|
||||
|
|
|
@ -65,10 +65,12 @@ namespace cryptonote
|
|||
{
|
||||
uint64_t height;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -113,6 +115,7 @@ namespace cryptonote
|
|||
uint64_t current_height;
|
||||
std::string status;
|
||||
std::vector<block_output_indices> output_indices;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(blocks)
|
||||
|
@ -120,6 +123,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(current_height)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(output_indices)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -138,10 +142,12 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<block_complete_entry> blocks;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(blocks)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -158,10 +164,12 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<std::string> blks_hashes;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(blks_hashes)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -184,12 +192,14 @@ namespace cryptonote
|
|||
uint64_t start_height;
|
||||
uint64_t current_height;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(m_block_ids)
|
||||
KV_SERIALIZE(start_height)
|
||||
KV_SERIALIZE(current_height)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -595,6 +605,7 @@ namespace cryptonote
|
|||
// new style
|
||||
std::vector<entry> txs;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(txs_as_hex)
|
||||
|
@ -602,6 +613,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(txs)
|
||||
KV_SERIALIZE(missed_tx)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -629,10 +641,12 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<int> spent_status;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(spent_status)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -653,9 +667,11 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<uint64_t> o_indexes;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(o_indexes)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -695,9 +711,11 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<outs_for_amount> outs;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(outs)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -745,10 +763,12 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<outkey> outs;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(outs)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -785,10 +805,12 @@ namespace cryptonote
|
|||
{
|
||||
std::vector<outkey> outs;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(outs)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -817,9 +839,11 @@ namespace cryptonote
|
|||
{
|
||||
std::list<out_entry> outs;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -854,6 +878,7 @@ namespace cryptonote
|
|||
bool overspend;
|
||||
bool fee_too_low;
|
||||
bool not_rct;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
|
@ -867,6 +892,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(overspend)
|
||||
KV_SERIALIZE(fee_too_low)
|
||||
KV_SERIALIZE(not_rct)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -930,6 +956,10 @@ namespace cryptonote
|
|||
uint64_t start_time;
|
||||
uint64_t free_space;
|
||||
bool offline;
|
||||
bool untrusted;
|
||||
std::string bootstrap_daemon_address;
|
||||
uint64_t height_without_bootstrap;
|
||||
bool was_bootstrap_ever_used;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
|
@ -953,6 +983,10 @@ namespace cryptonote
|
|||
KV_SERIALIZE(start_time)
|
||||
KV_SERIALIZE(free_space)
|
||||
KV_SERIALIZE(offline)
|
||||
KV_SERIALIZE(untrusted)
|
||||
KV_SERIALIZE(bootstrap_daemon_address)
|
||||
KV_SERIALIZE(height_without_bootstrap)
|
||||
KV_SERIALIZE(was_bootstrap_ever_used)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1080,6 +1114,7 @@ namespace cryptonote
|
|||
blobdata blocktemplate_blob;
|
||||
blobdata blockhashing_blob;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(difficulty)
|
||||
|
@ -1090,6 +1125,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(blocktemplate_blob)
|
||||
KV_SERIALIZE(blockhashing_blob)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1153,10 +1189,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
block_header_response block_header;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(block_header)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
@ -1177,10 +1215,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
block_header_response block_header;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(block_header)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
@ -1201,10 +1241,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
block_header_response block_header;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(block_header)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
@ -1231,6 +1273,7 @@ namespace cryptonote
|
|||
std::vector<std::string> tx_hashes;
|
||||
std::string blob;
|
||||
std::string json;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(block_header)
|
||||
|
@ -1239,6 +1282,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(blob)
|
||||
KV_SERIALIZE(json)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
@ -1415,11 +1459,13 @@ namespace cryptonote
|
|||
std::string status;
|
||||
std::vector<tx_info> transactions;
|
||||
std::vector<spent_key_image_info> spent_key_images;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(transactions)
|
||||
KV_SERIALIZE(spent_key_images)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1436,10 +1482,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
std::vector<crypto::hash> tx_hashes;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(tx_hashes)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1463,10 +1511,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
std::vector<tx_backlog_entry> backlog;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(backlog)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1527,10 +1577,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
txpool_stats pool_stats;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(pool_stats)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1573,10 +1625,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
std::vector<block_header_response> headers;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(headers)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1630,11 +1684,13 @@ namespace cryptonote
|
|||
std::string status;
|
||||
uint64_t limit_up;
|
||||
uint64_t limit_down;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(limit_up)
|
||||
KV_SERIALIZE(limit_down)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1744,6 +1800,7 @@ namespace cryptonote
|
|||
uint32_t state;
|
||||
uint64_t earliest_height;
|
||||
std::string status;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(version)
|
||||
|
@ -1755,6 +1812,7 @@ namespace cryptonote
|
|||
KV_SERIALIZE(state)
|
||||
KV_SERIALIZE(earliest_height)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1891,10 +1949,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
std::vector<entry> histogram;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(histogram)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1911,10 +1971,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
uint32_t version;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(version)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
@ -1961,10 +2023,12 @@ namespace cryptonote
|
|||
{
|
||||
std::string status;
|
||||
uint64_t fee;
|
||||
bool untrusted;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(fee)
|
||||
KV_SERIALIZE(untrusted)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue