From ca23c0e5c8fc1320a7172cd88e14298c8ad3171c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 13 Oct 2015 21:37:35 +0100 Subject: [PATCH 1/2] 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; From 253ed76ef4c55160d9defb673676943313da7786 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 13 Oct 2015 22:11:52 +0100 Subject: [PATCH 2/2] core_rpc_server: add optional json decoded tx to COMMAND_RPC_GET_TRANSACTIONS --- src/rpc/core_rpc_server.cpp | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 248ba17ac..08005ec72 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -253,6 +253,8 @@ namespace cryptonote { blobdata blob = t_serializable_object_to_blob(tx); res.txs_as_hex.push_back(string_tools::buff_to_hex_nodelimer(blob)); + if (req.decode_as_json) + res.txs_as_json.push_back(obj_to_json_str(tx)); } BOOST_FOREACH(const auto& miss_tx, missed_txs) diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 511a74bf1..cb8845e8c 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -95,9 +95,11 @@ namespace cryptonote struct request { std::list txs_hashes; + bool decode_as_json; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txs_hashes) + KV_SERIALIZE(decode_as_json) END_KV_SERIALIZE_MAP() }; @@ -106,11 +108,13 @@ namespace cryptonote { std::list txs_as_hex; //transactions blobs as hex std::list missed_tx; //not found transactions + std::list txs_as_json; //transactions decoded as json std::string status; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txs_as_hex) KV_SERIALIZE(missed_tx) + KV_SERIALIZE(txs_as_json) KV_SERIALIZE(status) END_KV_SERIALIZE_MAP() };