mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
GET_BLOCK
This commit is contained in:
parent
129e6f204c
commit
285e89ecda
8 changed files with 74 additions and 81 deletions
|
@ -773,31 +773,40 @@ bool rpc_command_executor::print_height() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool rpc_command_executor::print_block(GET_BLOCK::request&& req, bool include_hex) {
|
||||
req.fill_pow_hash = true;
|
||||
GET_BLOCK::response res{};
|
||||
|
||||
if (!invoke<GET_BLOCK>(std::move(req), res, "Block retrieval failed"))
|
||||
bool rpc_command_executor::print_block_by_hash(const crypto::hash& block_hash, bool include_hex) {
|
||||
auto maybe_block = try_running([this, &block_hash] {
|
||||
return invoke<GET_BLOCK>(json{
|
||||
{"hash", tools::type_to_hex(block_hash)},
|
||||
{"fill_pow_hash", true}});
|
||||
}, "Block retrieval failed");
|
||||
if (!maybe_block)
|
||||
return false;
|
||||
auto& block = *maybe_block;
|
||||
|
||||
if (include_hex)
|
||||
tools::success_msg_writer() << res.blob << std::endl;
|
||||
print_block_header(res.block_header);
|
||||
tools::success_msg_writer() << res.json << "\n";
|
||||
tools::success_msg_writer() << block["blob"] << std::endl;
|
||||
print_block_header(block["block_header"]);
|
||||
tools::success_msg_writer() << block["json"] << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rpc_command_executor::print_block_by_hash(const crypto::hash& block_hash, bool include_hex) {
|
||||
GET_BLOCK::request req{};
|
||||
req.hash = tools::type_to_hex(block_hash);
|
||||
return print_block(std::move(req), include_hex);
|
||||
}
|
||||
|
||||
bool rpc_command_executor::print_block_by_height(uint64_t height, bool include_hex) {
|
||||
GET_BLOCK::request req{};
|
||||
req.height = height;
|
||||
return print_block(std::move(req), include_hex);
|
||||
auto maybe_block = try_running([this, height] {
|
||||
return invoke<GET_BLOCK>(json{
|
||||
{"height", height},
|
||||
{"fill_pow_hash", true}});
|
||||
}, "Block retrieval failed");
|
||||
if (!maybe_block)
|
||||
return false;
|
||||
auto& block = *maybe_block;
|
||||
|
||||
if (include_hex)
|
||||
tools::success_msg_writer() << block["blob"] << std::endl;
|
||||
print_block_header(block["block_header"]);
|
||||
tools::success_msg_writer() << block["json"] << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rpc_command_executor::print_transaction(const crypto::hash& transaction_hash,
|
||||
|
|
|
@ -170,9 +170,6 @@ public:
|
|||
|
||||
bool print_height();
|
||||
|
||||
private:
|
||||
bool print_block(cryptonote::rpc::GET_BLOCK::request&& req, bool include_hdex);
|
||||
|
||||
public:
|
||||
bool print_block_by_hash(const crypto::hash& block_hash, bool include_hex);
|
||||
|
||||
|
|
|
@ -1793,45 +1793,43 @@ namespace cryptonote::rpc {
|
|||
return;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
GET_BLOCK::response core_rpc_server::invoke(GET_BLOCK::request&& req, rpc_context context)
|
||||
void core_rpc_server::invoke(GET_BLOCK& get_block, rpc_context context)
|
||||
{
|
||||
GET_BLOCK::response res{};
|
||||
|
||||
PERF_TIMER(on_get_block);
|
||||
if (use_bootstrap_daemon_if_necessary<GET_BLOCK>(req, res))
|
||||
return res;
|
||||
|
||||
block blk;
|
||||
uint64_t block_height;
|
||||
bool orphan = false;
|
||||
crypto::hash block_hash;
|
||||
if (!req.hash.empty())
|
||||
if (!get_block.request.hash.empty())
|
||||
{
|
||||
if (!tools::hex_to_type(req.hash, block_hash))
|
||||
throw rpc_error{ERROR_WRONG_PARAM, "Failed to parse hex representation of block hash. Hex = " + req.hash + '.'};
|
||||
if (!tools::hex_to_type(get_block.request.hash, block_hash))
|
||||
throw rpc_error{ERROR_WRONG_PARAM, "Failed to parse hex representation of block hash. Hex = " + get_block.request.hash + '.'};
|
||||
if (!m_core.get_block_by_hash(block_hash, blk, &orphan))
|
||||
throw rpc_error{ERROR_INTERNAL, "Internal error: can't get block by hash. Hash = " + req.hash + '.'};
|
||||
throw rpc_error{ERROR_INTERNAL, "Internal error: can't get block by hash. Hash = " + get_block.request.hash + '.'};
|
||||
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"};
|
||||
block_height = var::get<txin_gen>(blk.miner_tx.vin.front()).height;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto curr_height = m_core.get_current_blockchain_height(); req.height >= curr_height)
|
||||
throw rpc_error{ERROR_TOO_BIG_HEIGHT, std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(curr_height - 1)};
|
||||
if (!m_core.get_block_by_height(req.height, blk))
|
||||
throw rpc_error{ERROR_INTERNAL, "Internal error: can't get block by height. Height = " + std::to_string(req.height) + '.'};
|
||||
if (auto curr_height = m_core.get_current_blockchain_height(); get_block.request.height >= curr_height)
|
||||
throw rpc_error{ERROR_TOO_BIG_HEIGHT, std::string("Requested block height: ") + std::to_string(get_block.request.height) + " greater than current top block height: " + std::to_string(curr_height - 1)};
|
||||
if (!m_core.get_block_by_height(get_block.request.height, blk))
|
||||
throw rpc_error{ERROR_INTERNAL, "Internal error: can't get block by height. Height = " + std::to_string(get_block.request.height) + '.'};
|
||||
block_hash = get_block_hash(blk);
|
||||
block_height = req.height;
|
||||
block_height = get_block.request.height;
|
||||
}
|
||||
fill_block_header_response(blk, orphan, block_height, block_hash, res.block_header, req.fill_pow_hash && context.admin, false /*tx hashes*/);
|
||||
res.tx_hashes.reserve(blk.tx_hashes.size());
|
||||
for (const auto& tx_hash : blk.tx_hashes)
|
||||
res.tx_hashes.push_back(tools::type_to_hex(tx_hash));
|
||||
res.blob = oxenmq::to_hex(t_serializable_object_to_blob(blk));
|
||||
res.json = obj_to_json_str(blk);
|
||||
res.status = STATUS_OK;
|
||||
return res;
|
||||
block_header_response header;
|
||||
fill_block_header_response(blk, orphan, block_height, block_hash, header, get_block.request.fill_pow_hash && context.admin, false /*tx hashes*/);
|
||||
get_block.response["block_header"] = header;
|
||||
std::vector<std::string> tx_hashes;
|
||||
tx_hashes.reserve(blk.tx_hashes.size());
|
||||
std::transform(blk.tx_hashes.begin(), blk.tx_hashes.end(), tx_hashes.begin(), [](const auto& x) { return tools::type_to_hex(x); });
|
||||
get_block.response["tx_hashes"] = tx_hashes;
|
||||
get_block.response["blob"] = oxenmq::to_hex(t_serializable_object_to_blob(blk));
|
||||
get_block.response["json"] = obj_to_json_str(blk);
|
||||
get_block.response["status"] = STATUS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
static json json_connection_info(const connection_info& ci) {
|
||||
|
|
|
@ -256,6 +256,7 @@ namespace cryptonote::rpc {
|
|||
void invoke(RELAY_TX& relay_tx, rpc_context context);
|
||||
void invoke(GET_BLOCK_HEADERS_RANGE& get_block_headers_range, rpc_context context);
|
||||
void invoke(GET_BLOCK_HEADER_BY_HEIGHT& get_block_header_by_height, rpc_context context);
|
||||
void invoke(GET_BLOCK& get_block, 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);
|
||||
|
@ -267,11 +268,10 @@ namespace cryptonote::rpc {
|
|||
GET_OUTPUTS_BIN::response invoke(GET_OUTPUTS_BIN::request&& req, rpc_context context);
|
||||
GET_TRANSACTION_POOL_HASHES_BIN::response invoke(GET_TRANSACTION_POOL_HASHES_BIN::request&& req, rpc_context context);
|
||||
GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN::response invoke(GET_TX_GLOBAL_OUTPUTS_INDEXES_BIN::request&& req, rpc_context context);
|
||||
GET_OUTPUT_DISTRIBUTION::response invoke(GET_OUTPUT_DISTRIBUTION::request&& req, rpc_context context, bool binary = false);
|
||||
|
||||
// FIXME: unconverted JSON RPC endpoints:
|
||||
SET_BOOTSTRAP_DAEMON::response invoke(SET_BOOTSTRAP_DAEMON::request&& req, rpc_context context);
|
||||
GET_OUTPUT_DISTRIBUTION::response invoke(GET_OUTPUT_DISTRIBUTION::request&& req, rpc_context context, bool binary = false);
|
||||
GET_BLOCK::response invoke(GET_BLOCK::request&& req, rpc_context context);
|
||||
GET_OUTPUT_HISTOGRAM::response invoke(GET_OUTPUT_HISTOGRAM::request&& req, rpc_context context);
|
||||
GET_ALTERNATE_CHAINS::response invoke(GET_ALTERNATE_CHAINS::request&& req, rpc_context context);
|
||||
GET_QUORUM_STATE::response invoke(GET_QUORUM_STATE::request&& req, rpc_context context);
|
||||
|
|
|
@ -503,4 +503,10 @@ namespace cryptonote::rpc {
|
|||
get_values(in, "fill_pow_hash", get_block_header_by_height.request.fill_pow_hash);
|
||||
get_values(in, "get_tx_hashes", get_block_header_by_height.request.get_tx_hashes);
|
||||
}
|
||||
|
||||
void parse_request(GET_BLOCK& get_block, rpc_input in) {
|
||||
get_values(in, "hash", get_block.request.hash);
|
||||
get_values(in, "height", get_block.request.height);
|
||||
get_values(in, "fill_pow_hash", get_block.request.fill_pow_hash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,5 @@ namespace cryptonote::rpc {
|
|||
void parse_request(GET_STAKING_REQUIREMENT& get_staking_requirement, rpc_input in);
|
||||
void parse_request(GET_BLOCK_HEADERS_RANGE& get_block_headers_range, rpc_input in);
|
||||
void parse_request(GET_BLOCK_HEADER_BY_HEIGHT& get_block_header_by_height, rpc_input in);
|
||||
void parse_request(GET_BLOCK& get_block, rpc_input in);
|
||||
}
|
||||
|
|
|
@ -103,23 +103,6 @@ KV_SERIALIZE_MAP_CODE_BEGIN(block_header_response)
|
|||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK::request)
|
||||
KV_SERIALIZE(hash)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE_OPT(fill_pow_hash, false);
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_BLOCK::response)
|
||||
KV_SERIALIZE(block_header)
|
||||
KV_SERIALIZE(tx_hashes)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(blob)
|
||||
KV_SERIALIZE(json)
|
||||
KV_SERIALIZE(untrusted)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(SET_BOOTSTRAP_DAEMON::request)
|
||||
KV_SERIALIZE(address)
|
||||
KV_SERIALIZE(username)
|
||||
|
|
|
@ -846,33 +846,32 @@ namespace cryptonote::rpc {
|
|||
} request;
|
||||
};
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
// Full block information can be retrieved by either block height or hash, like with the above block header calls.
|
||||
// For full block information, both lookups use the same method, but with different input parameters.
|
||||
/// Full block information can be retrieved by either block height or hash, like with the above block header calls.
|
||||
/// For full block information, both lookups use the same method, but with different input parameters.
|
||||
///
|
||||
/// Inputs:
|
||||
///
|
||||
/// - \p hash The block's hash.
|
||||
/// - \p height A block height to look up; returned in `block_header`
|
||||
/// - \p fill_pow_hash Tell the daemon if it should fill out pow_hash field.
|
||||
///
|
||||
/// 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 `height` block
|
||||
/// - \p tx_hashes List of hashes of non-coinbase transactions in the block. If there are no other transactions, this will be an empty list.
|
||||
/// - \p blob Hexadecimal blob of block information.
|
||||
/// - \p json JSON formatted block details.
|
||||
struct GET_BLOCK : PUBLIC
|
||||
{
|
||||
static constexpr auto names() { return NAMES("get_block", "getblock"); }
|
||||
|
||||
struct request
|
||||
struct request_parameters
|
||||
{
|
||||
std::string hash; // The block's hash.
|
||||
uint64_t height; // The block's height.
|
||||
bool fill_pow_hash; // Tell the daemon if it should fill out pow_hash field.
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status; // General RPC error code. "OK" means everything looks good.
|
||||
block_header_response block_header; // A structure containing block header information. See get_last_block_header.
|
||||
std::vector<std::string> tx_hashes; // List of hashes of non-coinbase transactions in the block. If there are no other transactions, this will be an empty list.
|
||||
std::string blob; // Hexadecimal blob of block information.
|
||||
std::string json; // JSON formatted block details.
|
||||
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;
|
||||
};
|
||||
|
||||
/// Get the list of current network peers known to this node.
|
||||
|
|
Loading…
Reference in a new issue