From ca23c0e5c8fc1320a7172cd88e14298c8ad3171c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 13 Oct 2015 21:37:35 +0100 Subject: [PATCH] core_rpc_server: add a getblock RPC command, and fix print_block --- src/daemon/rpc_command_executor.cpp | 18 ++++---- src/rpc/core_rpc_server.cpp | 60 +++++++++++++++++++++++++ src/rpc/core_rpc_server.h | 2 + src/rpc/core_rpc_server_commands_defs.h | 32 +++++++++++++ 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index c4fe642e8..b0fe5945b 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -408,8 +408,8 @@ bool t_rpc_command_executor::print_height() { } bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) { - cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request req; - cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response res; + cryptonote::COMMAND_RPC_GET_BLOCK::request req; + cryptonote::COMMAND_RPC_GET_BLOCK::response res; epee::json_rpc::error error_resp; req.hash = epee::string_tools::pod_to_hex(block_hash); @@ -418,14 +418,14 @@ bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) { if (m_is_rpc) { - if (!m_rpc_client->json_rpc_request(req, res, "getblockheaderbyhash", fail_message.c_str())) + if (!m_rpc_client->json_rpc_request(req, res, "getblock", fail_message.c_str())) { return true; } } else { - if (!m_rpc_server->on_get_block_header_by_hash(req, res, error_resp)) + if (!m_rpc_server->on_get_block(req, res, error_resp)) { tools::fail_msg_writer() << fail_message.c_str(); return true; @@ -433,13 +433,14 @@ bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) { } print_block_header(res.block_header); + tools::success_msg_writer() << res.json << ENDL; return true; } bool t_rpc_command_executor::print_block_by_height(uint64_t height) { - cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request req; - cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response res; + cryptonote::COMMAND_RPC_GET_BLOCK::request req; + cryptonote::COMMAND_RPC_GET_BLOCK::response res; epee::json_rpc::error error_resp; req.height = height; @@ -448,14 +449,14 @@ bool t_rpc_command_executor::print_block_by_height(uint64_t height) { if (m_is_rpc) { - if (!m_rpc_client->json_rpc_request(req, res, "getblockheaderbyheight", fail_message.c_str())) + if (!m_rpc_client->json_rpc_request(req, res, "getblock", fail_message.c_str())) { return true; } } else { - if (!m_rpc_server->on_get_block_header_by_height(req, res, error_resp)) + if (!m_rpc_server->on_get_block(req, res, error_resp)) { tools::fail_msg_writer() << fail_message.c_str(); return true; @@ -463,6 +464,7 @@ bool t_rpc_command_executor::print_block_by_height(uint64_t height) { } print_block_header(res.block_header); + tools::success_msg_writer() << res.json << ENDL; return true; } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index f9ff632ac..248ba17ac 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -772,6 +772,66 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + 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){ + if(!check_core_busy()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + crypto::hash block_hash; + if (!req.hash.empty()) + { + bool hash_parsed = parse_hash256(req.hash, block_hash); + if(!hash_parsed) + { + error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; + error_resp.message = "Failed to parse hex representation of block hash. Hex = " + req.hash + '.'; + return false; + } + } + else + { + if(m_core.get_current_blockchain_height() <= req.height) + { + error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT; + error_resp.message = std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.get_current_blockchain_height()); + return false; + } + block_hash = m_core.get_block_id_by_height(req.height); + } + block blk; + bool have_block = m_core.get_block_by_hash(block_hash, blk); + if (!have_block) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.'; + return false; + } + if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: coinbase transaction in the block has the wrong type"; + return false; + } + uint64_t block_height = boost::get(blk.miner_tx.vin.front()).height; + bool responce_filled = fill_block_header_responce(blk, false, block_height, block_hash, res.block_header); + if (!responce_filled) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't produce valid response."; + return false; + } + for (size_t n = 0; n < blk.tx_hashes.size(); ++n) + { + res.tx_hashes.push_back(epee::string_tools::pod_to_hex(blk.tx_hashes[n])); + } + res.blob = t_serializable_object_to_blob(blk); + res.json = obj_to_json_str(blk); + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp) { if(!check_core_busy()) diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 60e7d00d5..4f62f92ac 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -101,6 +101,7 @@ namespace cryptonote MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) MAP_JON_RPC_WE("getblockheaderbyhash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) MAP_JON_RPC_WE("getblockheaderbyheight", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT) + MAP_JON_RPC_WE("getblock", on_get_block, COMMAND_RPC_GET_BLOCK) MAP_JON_RPC_WE("get_connections", on_get_connections, COMMAND_RPC_GET_CONNECTIONS) MAP_JON_RPC_WE("get_info", on_get_info_json, COMMAND_RPC_GET_INFO) END_JSON_RPC_MAP() @@ -136,6 +137,7 @@ namespace cryptonote bool 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); bool 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); bool 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); + bool on_get_block(const COMMAND_RPC_GET_BLOCK::request& req, COMMAND_RPC_GET_BLOCK::response& res, epee::json_rpc::error& error_resp); bool on_get_connections(const COMMAND_RPC_GET_CONNECTIONS::request& req, COMMAND_RPC_GET_CONNECTIONS::response& res, epee::json_rpc::error& error_resp); bool on_get_info_json(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, epee::json_rpc::error& error_resp); bool 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); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index a806cbae9..511a74bf1 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -536,6 +536,38 @@ namespace cryptonote }; + struct COMMAND_RPC_GET_BLOCK + { + struct request + { + std::string hash; + uint64_t height; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hash) + KV_SERIALIZE(height) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + block_header_responce block_header; + std::vector tx_hashes; + std::string blob; + std::string json; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(block_header) + KV_SERIALIZE(tx_hashes) + KV_SERIALIZE(status) + KV_SERIALIZE(blob) + KV_SERIALIZE(json) + END_KV_SERIALIZE_MAP() + }; + + }; + struct peer { uint64_t id; uint32_t ip;