mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
GET_BLOCK_HEADER_BY_HASH
This commit is contained in:
parent
445fab4ac5
commit
d476f216cc
7 changed files with 52 additions and 58 deletions
|
@ -1316,21 +1316,21 @@ bool rpc_command_executor::alt_chain_info(const std::string &tip, size_t above,
|
|||
for (const std::string &block_id: chain.block_hashes)
|
||||
tools::msg_writer() << " " << block_id;
|
||||
tools::msg_writer() << "Chain parent on main chain: " << chain.main_chain_parent_block;
|
||||
GET_BLOCK_HEADER_BY_HASH::request bhreq{};
|
||||
GET_BLOCK_HEADER_BY_HASH::response bhres{};
|
||||
bhreq.hashes = chain.block_hashes;
|
||||
bhreq.hashes.push_back(chain.main_chain_parent_block);
|
||||
bhreq.fill_pow_hash = false;
|
||||
if (!invoke<GET_BLOCK_HEADER_BY_HASH>(std::move(bhreq), bhres, "Failed to query block header by hash"))
|
||||
return false;
|
||||
|
||||
if (bhres.block_headers.size() != chain.length + 1)
|
||||
std::vector<std::string> hashes{chain.block_hashes};
|
||||
hashes.push_back(chain.main_chain_parent_block);
|
||||
auto maybe_headers = try_running([&] { return invoke<GET_BLOCK_HEADER_BY_HASH>(json{{"hashes", hashes}, {"fill_pow_hash", false}}); }, "Failed to query block header by hash");
|
||||
if (!maybe_headers)
|
||||
return false;
|
||||
auto headers = *maybe_headers;
|
||||
|
||||
if (headers["block_headers"].size() != chain.length + 1)
|
||||
{
|
||||
tools::fail_msg_writer() << "Failed to get block header info for alt chain";
|
||||
return true;
|
||||
}
|
||||
uint64_t t0 = bhres.block_headers.front().timestamp, t1 = t0;
|
||||
for (const block_header_response &block_header: bhres.block_headers)
|
||||
uint64_t t0 = headers["block_headers"].front()["timestamp"], t1 = t0;
|
||||
for (const block_header_response &block_header: headers["block_headers"])
|
||||
{
|
||||
t0 = std::min<uint64_t>(t0, block_header.timestamp);
|
||||
t1 = std::max<uint64_t>(t1, block_header.timestamp);
|
||||
|
@ -1341,11 +1341,11 @@ bool rpc_command_executor::alt_chain_info(const std::string &tip, size_t above,
|
|||
if (chain.length > 1)
|
||||
{
|
||||
tools::msg_writer() << "Time span: " << tools::get_human_readable_timespan(std::chrono::seconds(dt));
|
||||
cryptonote::difficulty_type start_difficulty = bhres.block_headers.back().difficulty;
|
||||
cryptonote::difficulty_type start_difficulty = headers["block_headers"].back()["difficulty"];
|
||||
if (start_difficulty > 0)
|
||||
tools::msg_writer() << "Approximated " << 100.f * tools::to_seconds(TARGET_BLOCK_TIME) * chain.length / dt << "% of network hash rate";
|
||||
else
|
||||
tools::fail_msg_writer() << "Bad cmumulative difficulty reported by dameon";
|
||||
tools::fail_msg_writer() << "Bad cumulative difficulty reported by dameon";
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1695,15 +1695,12 @@ namespace cryptonote::rpc {
|
|||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
GET_BLOCK_HEADER_BY_HASH::response core_rpc_server::invoke(GET_BLOCK_HEADER_BY_HASH::request&& req, rpc_context context)
|
||||
void core_rpc_server::invoke(GET_BLOCK_HEADER_BY_HASH& get_block_header_by_hash, rpc_context context)
|
||||
{
|
||||
GET_BLOCK_HEADER_BY_HASH::response res{};
|
||||
|
||||
PERF_TIMER(on_get_block_header_by_hash);
|
||||
if (use_bootstrap_daemon_if_necessary<GET_BLOCK_HEADER_BY_HASH>(req, res))
|
||||
return res;
|
||||
|
||||
auto get = [this, &req, admin=context.admin](const std::string &hash, block_header_response &block_header) {
|
||||
auto get = [this, &get_block_header_by_hash, admin=context.admin](const std::string &hash, block_header_response &block_header) {
|
||||
crypto::hash block_hash;
|
||||
if (!tools::hex_to_type(hash, block_hash))
|
||||
throw rpc_error{ERROR_WRONG_PARAM, "Failed to parse hex representation of block hash. Hex = " + hash + '.'};
|
||||
|
@ -1715,18 +1712,23 @@ namespace cryptonote::rpc {
|
|||
if (blk.miner_tx.vin.size() != 1 || !std::holds_alternative<txin_gen>(blk.miner_tx.vin.front()))
|
||||
throw rpc_error{ERROR_INTERNAL, "Internal error: coinbase transaction in the block has the wrong type"};
|
||||
uint64_t block_height = var::get<txin_gen>(blk.miner_tx.vin.front()).height;
|
||||
fill_block_header_response(blk, orphan, block_height, block_hash, block_header, req.fill_pow_hash && admin, req.get_tx_hashes);
|
||||
fill_block_header_response(blk, orphan, block_height, block_hash, block_header, get_block_header_by_hash.request.fill_pow_hash && admin, get_block_header_by_hash.request.get_tx_hashes);
|
||||
};
|
||||
|
||||
if (!req.hash.empty())
|
||||
get(req.hash, res.block_header.emplace());
|
||||
if (!get_block_header_by_hash.request.hash.empty())
|
||||
{
|
||||
block_header_response block_header;
|
||||
get(get_block_header_by_hash.request.hash, block_header);
|
||||
get_block_header_by_hash.response["block_header"] = block_header;
|
||||
}
|
||||
|
||||
res.block_headers.reserve(req.hashes.size());
|
||||
for (const std::string &hash: req.hashes)
|
||||
get(hash, res.block_headers.emplace_back());
|
||||
std::vector<block_header_response> block_headers;
|
||||
for (const std::string &hash: get_block_header_by_hash.request.hashes)
|
||||
get(hash, block_headers.emplace_back());
|
||||
|
||||
res.status = STATUS_OK;
|
||||
return res;
|
||||
get_block_header_by_hash.response["block_headers"] = block_headers;
|
||||
get_block_header_by_hash.response["status"] = STATUS_OK;
|
||||
return;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
GET_BLOCK_HEADERS_RANGE::response core_rpc_server::invoke(GET_BLOCK_HEADERS_RANGE::request&& req, rpc_context context)
|
||||
|
|
|
@ -245,6 +245,7 @@ namespace cryptonote::rpc {
|
|||
void invoke(REPORT_PEER_STATUS& report_peer_status, rpc_context context);
|
||||
void invoke(FLUSH_CACHE& flush_cache, rpc_context context);
|
||||
void invoke(GET_LAST_BLOCK_HEADER& get_last_block_header, rpc_context context);
|
||||
void invoke(GET_BLOCK_HEADER_BY_HASH& get_block_header_by_hash, rpc_context context);
|
||||
|
||||
// Deprecated Monero NIH binary endpoints:
|
||||
GET_ALT_BLOCKS_HASHES_BIN::response invoke(GET_ALT_BLOCKS_HASHES_BIN::request&& req, rpc_context context);
|
||||
|
@ -260,7 +261,6 @@ namespace cryptonote::rpc {
|
|||
// FIXME: unconverted JSON RPC endpoints:
|
||||
SET_BOOTSTRAP_DAEMON::response invoke(SET_BOOTSTRAP_DAEMON::request&& req, rpc_context context);
|
||||
GET_OUTPUT_DISTRIBUTION::response invoke(GET_OUTPUT_DISTRIBUTION::request&& req, rpc_context context, bool binary = false);
|
||||
GET_BLOCK_HEADER_BY_HASH::response invoke(GET_BLOCK_HEADER_BY_HASH::request&& req, rpc_context context);
|
||||
GET_BLOCK_HEADER_BY_HEIGHT::response invoke(GET_BLOCK_HEADER_BY_HEIGHT::request&& req, rpc_context context);
|
||||
GET_BLOCK_HEADERS_RANGE::response invoke(GET_BLOCK_HEADERS_RANGE::request&& req, rpc_context context);
|
||||
GET_BLOCK::response invoke(GET_BLOCK::request&& req, rpc_context context);
|
||||
|
|
|
@ -471,4 +471,11 @@ namespace cryptonote::rpc {
|
|||
get_values(in, "fill_pow_hash", get_last_block_header.request.fill_pow_hash);
|
||||
get_values(in, "get_tx_hashes", get_last_block_header.request.get_tx_hashes);
|
||||
}
|
||||
|
||||
void parse_request(GET_BLOCK_HEADER_BY_HASH& get_block_header_by_hash, rpc_input in) {
|
||||
get_values(in, "hash", get_block_header_by_hash.request.hash);
|
||||
get_values(in, "hashes", get_block_header_by_hash.request.hashes);
|
||||
get_values(in, "fill_pow_hash", get_block_header_by_hash.request.fill_pow_hash);
|
||||
get_values(in, "get_tx_hashes", get_block_header_by_hash.request.get_tx_hashes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,5 +37,6 @@ namespace cryptonote::rpc {
|
|||
void parse_request(GET_SN_STATE_CHANGES& get_sn_state_changes, rpc_input in);
|
||||
void parse_request(REPORT_PEER_STATUS& report_peer_status, rpc_input in);
|
||||
void parse_request(FLUSH_CACHE& flush_cache, rpc_input in);
|
||||
void parse_request(GET_LAST_BLOCK_HEADER& get_lash_block_header, rpc_input in);
|
||||
void parse_request(GET_LAST_BLOCK_HEADER& get_last_block_header, rpc_input in);
|
||||
void parse_request(GET_BLOCK_HEADER_BY_HASH& get_block_header_by_hash, rpc_input in);
|
||||
}
|
||||
|
|
|
@ -102,22 +102,6 @@ KV_SERIALIZE_MAP_CODE_BEGIN(block_header_response)
|
|||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK_HEADER_BY_HASH::request)
|
||||
KV_SERIALIZE(hash)
|
||||
KV_SERIALIZE(hashes)
|
||||
KV_SERIALIZE_OPT(fill_pow_hash, false);
|
||||
KV_SERIALIZE_OPT(get_tx_hashes, false);
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK_HEADER_BY_HASH::response)
|
||||
KV_SERIALIZE(block_header)
|
||||
KV_SERIALIZE(block_headers)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(untrusted)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK_HEADER_BY_HEIGHT::request)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(heights)
|
||||
|
|
|
@ -793,30 +793,30 @@ namespace cryptonote::rpc {
|
|||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
// Block header information can be retrieved using either a block's hash or height. This method includes a block's hash as an input parameter to retrieve basic information about the block.
|
||||
/// Block header information can be retrieved using either a block's hash or height. This method includes a block's hash as an input parameter to retrieve basic information about the block.
|
||||
///
|
||||
/// Inputs:
|
||||
/// - \p hash The block's SHA256 hash.
|
||||
/// - \p hashes Request multiple blocks via an array of hashes
|
||||
/// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field.
|
||||
/// - \p get_tx_hashes If true (default false) then include the hashes of non-coinbase transactions
|
||||
///
|
||||
/// Output values available from a public RPC endpoint:
|
||||
///
|
||||
/// - \p status General RPC status string. `"OK"` means everything looks good.
|
||||
/// - \p block_header Block header information for the requested `hash` block
|
||||
/// - \p block_headers Block header information for the requested `hashes` blocks
|
||||
struct GET_BLOCK_HEADER_BY_HASH : PUBLIC
|
||||
{
|
||||
static constexpr auto names() { return NAMES("get_block_header_by_hash", "getblockheaderbyhash"); }
|
||||
|
||||
struct request
|
||||
struct request_parameters
|
||||
{
|
||||
std::string hash; // The block's SHA256 hash.
|
||||
std::vector<std::string> hashes; // Request multiple blocks via an array of hashes
|
||||
bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field.
|
||||
bool get_tx_hashes; // If true (default false) then include the hashes of non-coinbase transactions
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status; // General RPC error code. "OK" means everything looks good.
|
||||
std::optional<block_header_response> block_header; // Block header information for the requested `hash` block
|
||||
std::vector<block_header_response> block_headers; // Block header information for the requested `hashes` blocks
|
||||
bool untrusted; // States if the result is obtained using the bootstrap mode, and is therefore not trusted (`true`), or when the daemon is fully synced (`false`).
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
} request;
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
|
|
Loading…
Reference in a new issue