aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2017-09-05 12:20:40 -0400
committerThomas Winget <tewinget@gmail.com>2017-09-05 12:20:40 -0400
commit0299cb77ca18073daf3cf371f8da013fb596ae48 (patch)
tree14aa3b3c6ddbdf064246bb3800fec3e90c9b609d /src/rpc
parentjson serialization for rpc-relevant monero types (diff)
downloadmonero-0299cb77ca18073daf3cf371f8da013fb596ae48.tar.xz
Fix various oversights/bugs in ZMQ RPC server code
- Add some RPC commands (and touch up a couple others) - some bounds checking - some better pointer management - const correctness and error handling -- Thanks @vtnerd for type help with serialization and CMake changes
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/CMakeLists.txt2
-rw-r--r--src/rpc/daemon_handler.cpp171
-rw-r--r--src/rpc/daemon_handler.h6
-rw-r--r--src/rpc/daemon_messages.cpp152
-rw-r--r--src/rpc/daemon_messages.h47
-rw-r--r--src/rpc/daemon_rpc_version.h6
-rw-r--r--src/rpc/message.cpp2
-rw-r--r--src/rpc/message_data_structs.h20
-rw-r--r--src/rpc/zmq_server.cpp51
-rw-r--r--src/rpc/zmq_server.h9
10 files changed, 326 insertions, 140 deletions
diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt
index 717e3e627..b5c38b1a8 100644
--- a/src/rpc/CMakeLists.txt
+++ b/src/rpc/CMakeLists.txt
@@ -115,6 +115,8 @@ target_link_libraries(daemon_rpc_server
${Boost_THREAD_LIBRARY}
${ZMQ_LIB}
${EXTRA_LIBRARIES})
+target_include_directories(daemon_rpc_server PUBLIC ${ZMQ_INCLUDE_PATH})
+target_include_directories(obj_daemon_rpc_server PUBLIC ${ZMQ_INCLUDE_PATH})
add_dependencies(rpc
diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp
index 6a287b229..53eeb5e76 100644
--- a/src/rpc/daemon_handler.cpp
+++ b/src/rpc/daemon_handler.cpp
@@ -81,6 +81,14 @@ namespace rpc
return;
}
+ if (it->second.size() != bwt.block.tx_hashes.size())
+ {
+ res.blocks.clear();
+ res.output_indices.clear();
+ res.status = Message::STATUS_FAILED;
+ res.error_details = "incorrect number of transactions retrieved for block";
+ return;
+ }
std::list<transaction> txs;
for (const auto& blob : it->second)
{
@@ -90,7 +98,7 @@ namespace rpc
res.blocks.clear();
res.output_indices.clear();
res.status = Message::STATUS_FAILED;
- res.error_details = "failed retrieving a requested block";
+ res.error_details = "failed retrieving a requested transaction";
return;
}
}
@@ -404,56 +412,117 @@ namespace rpc
void DaemonHandler::handle(const StartMining::Request& req, StartMining::Response& res)
{
- res.status = Message::STATUS_FAILED;
- res.error_details = "RPC method not yet implemented.";
+ account_public_address adr;
+ if(!get_account_address_from_str(adr, m_core.get_testnet(), req.miner_address))
+ {
+ res.error_details = "Failed, wrong address";
+ LOG_PRINT_L0(res.error_details);
+ res.status = Message::STATUS_FAILED;
+ return;
+ }
+
+ unsigned int concurrency_count = boost::thread::hardware_concurrency() * 4;
+
+ // if we couldn't detect threads, set it to a ridiculously high number
+ if(concurrency_count == 0)
+ {
+ concurrency_count = 257;
+ }
+
+ // if there are more threads requested than the hardware supports
+ // then we fail and log that.
+ if(req.threads_count > concurrency_count)
+ {
+ res.error_details = "Failed, too many threads relative to CPU cores.";
+ LOG_PRINT_L0(res.error_details);
+ res.status = Message::STATUS_FAILED;
+ return;
+ }
+
+ boost::thread::attributes attrs;
+ attrs.set_stack_size(THREAD_STACK_SIZE);
+
+ if(!m_core.get_miner().start(adr, static_cast<size_t>(req.threads_count), attrs, req.do_background_mining, req.ignore_battery))
+ {
+ res.error_details = "Failed, mining not started";
+ LOG_PRINT_L0(res.error_details);
+ res.status = Message::STATUS_FAILED;
+ return;
+ }
+ res.status = Message::STATUS_OK;
+ res.error_details = "";
+
}
void DaemonHandler::handle(const GetInfo::Request& req, GetInfo::Response& res)
{
- res.height = m_core.get_current_blockchain_height();
+ res.info.height = m_core.get_current_blockchain_height();
- res.target_height = m_core.get_target_blockchain_height();
+ res.info.target_height = m_core.get_target_blockchain_height();
- if (res.height > res.target_height)
+ if (res.info.height > res.info.target_height)
{
- res.target_height = res.height;
+ res.info.target_height = res.info.height;
}
auto& chain = m_core.get_blockchain_storage();
- res.difficulty = chain.get_difficulty_for_next_block();
+ res.info.difficulty = chain.get_difficulty_for_next_block();
- res.target = chain.get_difficulty_target();
+ res.info.target = chain.get_difficulty_target();
- res.tx_count = chain.get_total_transactions() - res.height; //without coinbase
+ res.info.tx_count = chain.get_total_transactions() - res.info.height; //without coinbase
- res.tx_pool_size = m_core.get_pool_transactions_count();
+ res.info.tx_pool_size = m_core.get_pool_transactions_count();
- res.alt_blocks_count = chain.get_alternative_blocks_count();
+ res.info.alt_blocks_count = chain.get_alternative_blocks_count();
uint64_t total_conn = m_p2p.get_connections_count();
- res.outgoing_connections_count = m_p2p.get_outgoing_connections_count();
- res.incoming_connections_count = total_conn - res.outgoing_connections_count;
+ res.info.outgoing_connections_count = m_p2p.get_outgoing_connections_count();
+ res.info.incoming_connections_count = total_conn - res.info.outgoing_connections_count;
- res.white_peerlist_size = m_p2p.get_peerlist_manager().get_white_peers_count();
+ res.info.white_peerlist_size = m_p2p.get_peerlist_manager().get_white_peers_count();
- res.grey_peerlist_size = m_p2p.get_peerlist_manager().get_gray_peers_count();
+ res.info.grey_peerlist_size = m_p2p.get_peerlist_manager().get_gray_peers_count();
- res.testnet = m_core.get_testnet();
+ res.info.testnet = m_core.get_testnet();
+ res.info.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.info.height - 1);
+ res.info.block_size_limit = m_core.get_blockchain_storage().get_current_cumulative_blocksize_limit();
+ res.info.start_time = (uint64_t)m_core.get_start_time();
res.status = Message::STATUS_OK;
+ res.error_details = "";
}
void DaemonHandler::handle(const StopMining::Request& req, StopMining::Response& res)
{
- res.status = Message::STATUS_FAILED;
- res.error_details = "RPC method not yet implemented.";
+ if(!m_core.get_miner().stop())
+ {
+ res.error_details = "Failed, mining not stopped";
+ LOG_PRINT_L0(res.error_details);
+ res.status = Message::STATUS_FAILED;
+ return;
+ }
+
+ res.status = Message::STATUS_OK;
+ res.error_details = "";
}
void DaemonHandler::handle(const MiningStatus::Request& req, MiningStatus::Response& res)
{
- res.status = Message::STATUS_FAILED;
- res.error_details = "RPC method not yet implemented.";
+ const cryptonote::miner& lMiner = m_core.get_miner();
+ res.active = lMiner.is_mining();
+ res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled();
+
+ if ( lMiner.is_mining() ) {
+ res.speed = lMiner.get_speed();
+ res.threads_count = lMiner.get_threads_count();
+ const account_public_address& lMiningAdr = lMiner.get_mining_address();
+ res.address = get_account_address_as_str(m_core.get_testnet(), lMiningAdr);
+ }
+
+ res.status = Message::STATUS_OK;
+ res.error_details = "";
}
void DaemonHandler::handle(const SaveBC::Request& req, SaveBC::Response& res)
@@ -536,14 +605,31 @@ namespace rpc
res.status = Message::STATUS_OK;
}
+ void DaemonHandler::handle(const GetBlockHeadersByHeight::Request& req, GetBlockHeadersByHeight::Response& res)
+ {
+ res.headers.resize(req.heights.size());
+
+ for (size_t i=0; i < req.heights.size(); i++)
+ {
+ const crypto::hash block_hash = m_core.get_block_id_by_height(req.heights[i]);
+
+ if (!getBlockHeaderByHash(block_hash, res.headers[i]))
+ {
+ res.status = Message::STATUS_FAILED;
+ res.error_details = "A requested block does not exist";
+ return;
+ }
+ }
+
+ res.status = Message::STATUS_OK;
+ }
+
void DaemonHandler::handle(const GetBlock::Request& req, GetBlock::Response& res)
{
res.status = Message::STATUS_FAILED;
res.error_details = "RPC method not yet implemented.";
}
- //TODO: this RPC call is marked for later implementation in the old RPC,
- // need to sort out if it's necessary and what it should do.
void DaemonHandler::handle(const GetPeerList::Request& req, GetPeerList::Response& res)
{
res.status = Message::STATUS_FAILED;
@@ -596,18 +682,6 @@ namespace rpc
res.error_details = "RPC method not yet implemented.";
}
- void DaemonHandler::handle(const FastExit::Request& req, FastExit::Response& res)
- {
- res.status = Message::STATUS_FAILED;
- res.error_details = "RPC method not yet implemented.";
- }
-
- void DaemonHandler::handle(const OutPeers::Request& req, OutPeers::Response& res)
- {
- res.status = Message::STATUS_FAILED;
- res.error_details = "RPC method not yet implemented.";
- }
-
void DaemonHandler::handle(const StartSaveGraph::Request& req, StartSaveGraph::Response& res)
{
res.status = Message::STATUS_FAILED;
@@ -675,13 +749,22 @@ namespace rpc
void DaemonHandler::handle(const GetOutputKeys::Request& req, GetOutputKeys::Response& res)
{
- for (const auto& i : req.outputs)
+ try
{
- crypto::public_key key;
- rct::key mask;
- bool unlocked;
- m_core.get_blockchain_storage().get_output_key_mask_unlocked(i.amount, i.index, key, mask, unlocked);
- res.keys.emplace_back(output_key_mask_unlocked{key, mask, unlocked});
+ for (const auto& i : req.outputs)
+ {
+ crypto::public_key key;
+ rct::key mask;
+ bool unlocked;
+ m_core.get_blockchain_storage().get_output_key_mask_unlocked(i.amount, i.index, key, mask, unlocked);
+ res.keys.emplace_back(output_key_mask_unlocked{key, mask, unlocked});
+ }
+ }
+ catch (const std::exception& e)
+ {
+ res.status = Message::STATUS_FAILED;
+ res.error_details = e.what();
+ return;
}
res.status = Message::STATUS_OK;
@@ -689,7 +772,7 @@ namespace rpc
void DaemonHandler::handle(const GetRPCVersion::Request& req, GetRPCVersion::Response& res)
{
- res.version = DAEMON_RPC_VERSION;
+ res.version = DAEMON_RPC_VERSION_ZMQ;
res.status = Message::STATUS_OK;
}
@@ -754,11 +837,15 @@ namespace rpc
REQ_RESP_TYPES_MACRO(request_type, GetRandomOutputsForAmounts, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, SendRawTx, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetInfo, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, StartMining, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, StopMining, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, MiningStatus, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, SaveBC, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetBlockHash, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetLastBlockHeader, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetBlockHeaderByHash, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetBlockHeaderByHeight, req_json, resp_message, handle);
+ REQ_RESP_TYPES_MACRO(request_type, GetBlockHeadersByHeight, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetPeerList, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, SetLogLevel, req_json, resp_message, handle);
REQ_RESP_TYPES_MACRO(request_type, GetTransactionPool, req_json, resp_message, handle);
diff --git a/src/rpc/daemon_handler.h b/src/rpc/daemon_handler.h
index 9997956c7..0d356bad2 100644
--- a/src/rpc/daemon_handler.h
+++ b/src/rpc/daemon_handler.h
@@ -92,6 +92,8 @@ class DaemonHandler : public RpcHandler
void handle(const GetBlockHeaderByHeight::Request& req, GetBlockHeaderByHeight::Response& res);
+ void handle(const GetBlockHeadersByHeight::Request& req, GetBlockHeadersByHeight::Response& res);
+
void handle(const GetBlock::Request& req, GetBlock::Response& res);
void handle(const GetPeerList::Request& req, GetPeerList::Response& res);
@@ -108,10 +110,6 @@ class DaemonHandler : public RpcHandler
void handle(const StopDaemon::Request& req, StopDaemon::Response& res);
- void handle(const FastExit::Request& req, FastExit::Response& res);
-
- void handle(const OutPeers::Request& req, OutPeers::Response& res);
-
void handle(const StartSaveGraph::Request& req, StartSaveGraph::Response& res);
void handle(const StopSaveGraph::Request& req, StopSaveGraph::Response& res);
diff --git a/src/rpc/daemon_messages.cpp b/src/rpc/daemon_messages.cpp
index b999a0f18..640058df9 100644
--- a/src/rpc/daemon_messages.cpp
+++ b/src/rpc/daemon_messages.cpp
@@ -43,12 +43,16 @@ const char* const KeyImagesSpent::name = "key_images_spent";
const char* const GetTxGlobalOutputIndices::name = "get_tx_global_output_indices";
const char* const GetRandomOutputsForAmounts::name = "get_random_outputs_for_amounts";
const char* const SendRawTx::name = "send_raw_tx";
+const char* const StartMining::name = "start_mining";
+const char* const StopMining::name = "stop_mining";
+const char* const MiningStatus::name = "mining_status";
const char* const GetInfo::name = "get_info";
const char* const SaveBC::name = "save_bc";
const char* const GetBlockHash::name = "get_block_hash";
const char* const GetLastBlockHeader::name = "get_last_block_header";
const char* const GetBlockHeaderByHash::name = "get_block_header_by_hash";
const char* const GetBlockHeaderByHeight::name = "get_block_header_by_height";
+const char* const GetBlockHeadersByHeight::name = "get_block_headers_by_height";
const char* const GetPeerList::name = "get_peer_list";
const char* const SetLogLevel::name = "set_log_level";
const char* const GetTransactionPool::name = "get_transaction_pool";
@@ -95,6 +99,7 @@ rapidjson::Value GetBlocksFast::Request::toJson(rapidjson::Document& doc) const
INSERT_INTO_JSON_OBJECT(val, doc, block_ids, block_ids);
val.AddMember("start_height", start_height, al);
+ val.AddMember("prune", prune, al);
return val;
}
@@ -103,6 +108,7 @@ void GetBlocksFast::Request::fromJson(rapidjson::Value& val)
{
GET_FROM_JSON_OBJECT(val, block_ids, block_ids);
GET_FROM_JSON_OBJECT(val, start_height, start_height);
+ GET_FROM_JSON_OBJECT(val, prune, prune);
}
rapidjson::Value GetBlocksFast::Response::toJson(rapidjson::Document& doc) const
@@ -332,11 +338,96 @@ rapidjson::Value SendRawTx::Response::toJson(rapidjson::Document& doc) const
return val;
}
+
void SendRawTx::Response::fromJson(rapidjson::Value& val)
{
GET_FROM_JSON_OBJECT(val, relayed, relayed);
}
+rapidjson::Value StartMining::Request::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, miner_address, miner_address);
+ INSERT_INTO_JSON_OBJECT(val, doc, threads_count, threads_count);
+ INSERT_INTO_JSON_OBJECT(val, doc, do_background_mining, do_background_mining);
+ INSERT_INTO_JSON_OBJECT(val, doc, ignore_battery, ignore_battery);
+
+ return val;
+}
+
+void StartMining::Request::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, miner_address, miner_address);
+ GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
+ GET_FROM_JSON_OBJECT(val, do_background_mining, do_background_mining);
+ GET_FROM_JSON_OBJECT(val, ignore_battery, ignore_battery);
+}
+
+rapidjson::Value StartMining::Response::toJson(rapidjson::Document& doc) const
+{
+ return Message::toJson(doc);
+}
+
+void StartMining::Response::fromJson(rapidjson::Value& val)
+{
+}
+
+
+rapidjson::Value StopMining::Request::toJson(rapidjson::Document& doc) const
+{
+ return Message::toJson(doc);
+}
+
+void StopMining::Request::fromJson(rapidjson::Value& val)
+{
+}
+
+rapidjson::Value StopMining::Response::toJson(rapidjson::Document& doc) const
+{
+ return Message::toJson(doc);
+}
+
+void StopMining::Response::fromJson(rapidjson::Value& val)
+{
+}
+
+
+rapidjson::Value MiningStatus::Request::toJson(rapidjson::Document& doc) const
+{
+ return Message::toJson(doc);
+}
+
+void MiningStatus::Request::fromJson(rapidjson::Value& val)
+{
+}
+
+rapidjson::Value MiningStatus::Response::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, active, active);
+ INSERT_INTO_JSON_OBJECT(val, doc, speed, speed);
+ INSERT_INTO_JSON_OBJECT(val, doc, threads_count, threads_count);
+ INSERT_INTO_JSON_OBJECT(val, doc, address, address);
+ INSERT_INTO_JSON_OBJECT(val, doc, is_background_mining_enabled, is_background_mining_enabled);
+
+ return val;
+}
+
+void MiningStatus::Response::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, active, active);
+ GET_FROM_JSON_OBJECT(val, speed, speed);
+ GET_FROM_JSON_OBJECT(val, threads_count, threads_count);
+ GET_FROM_JSON_OBJECT(val, address, address);
+ GET_FROM_JSON_OBJECT(val, is_background_mining_enabled, is_background_mining_enabled);
+}
+
rapidjson::Value GetInfo::Request::toJson(rapidjson::Document& doc) const
{
@@ -353,38 +444,14 @@ rapidjson::Value GetInfo::Response::toJson(rapidjson::Document& doc) const
auto& al = doc.GetAllocator();
- INSERT_INTO_JSON_OBJECT(val, doc, height, height);
- INSERT_INTO_JSON_OBJECT(val, doc, target_height, target_height);
- INSERT_INTO_JSON_OBJECT(val, doc, difficulty, difficulty);
- INSERT_INTO_JSON_OBJECT(val, doc, target, target);
- INSERT_INTO_JSON_OBJECT(val, doc, tx_count, tx_count);
- INSERT_INTO_JSON_OBJECT(val, doc, tx_pool_size, tx_pool_size);
- INSERT_INTO_JSON_OBJECT(val, doc, alt_blocks_count, alt_blocks_count);
- INSERT_INTO_JSON_OBJECT(val, doc, outgoing_connections_count, outgoing_connections_count);
- INSERT_INTO_JSON_OBJECT(val, doc, incoming_connections_count, incoming_connections_count);
- INSERT_INTO_JSON_OBJECT(val, doc, white_peerlist_size, white_peerlist_size);
- INSERT_INTO_JSON_OBJECT(val, doc, grey_peerlist_size, grey_peerlist_size);
- INSERT_INTO_JSON_OBJECT(val, doc, testnet, testnet);
- INSERT_INTO_JSON_OBJECT(val, doc, top_block_hash, top_block_hash);
+ INSERT_INTO_JSON_OBJECT(val, doc, info, info);
return val;
}
void GetInfo::Response::fromJson(rapidjson::Value& val)
{
- GET_FROM_JSON_OBJECT(val, height, height);
- GET_FROM_JSON_OBJECT(val, target_height, target_height);
- GET_FROM_JSON_OBJECT(val, difficulty, difficulty);
- GET_FROM_JSON_OBJECT(val, target, target);
- GET_FROM_JSON_OBJECT(val, tx_count, tx_count);
- GET_FROM_JSON_OBJECT(val, tx_pool_size, tx_pool_size);
- GET_FROM_JSON_OBJECT(val, alt_blocks_count, alt_blocks_count);
- GET_FROM_JSON_OBJECT(val, outgoing_connections_count, outgoing_connections_count);
- GET_FROM_JSON_OBJECT(val, incoming_connections_count, incoming_connections_count);
- GET_FROM_JSON_OBJECT(val, white_peerlist_size, white_peerlist_size);
- GET_FROM_JSON_OBJECT(val, grey_peerlist_size, grey_peerlist_size);
- GET_FROM_JSON_OBJECT(val, testnet, testnet);
- GET_FROM_JSON_OBJECT(val, top_block_hash, top_block_hash);
+ GET_FROM_JSON_OBJECT(val, info, info);
}
@@ -544,6 +611,39 @@ void GetBlockHeaderByHeight::Response::fromJson(rapidjson::Value& val)
}
+rapidjson::Value GetBlockHeadersByHeight::Request::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, heights, heights);
+
+ return val;
+}
+
+void GetBlockHeadersByHeight::Request::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, heights, heights);
+}
+
+rapidjson::Value GetBlockHeadersByHeight::Response::toJson(rapidjson::Document& doc) const
+{
+ auto val = Message::toJson(doc);
+
+ auto& al = doc.GetAllocator();
+
+ INSERT_INTO_JSON_OBJECT(val, doc, headers, headers);
+
+ return val;
+}
+
+void GetBlockHeadersByHeight::Response::fromJson(rapidjson::Value& val)
+{
+ GET_FROM_JSON_OBJECT(val, headers, headers);
+}
+
+
rapidjson::Value GetPeerList::Request::toJson(rapidjson::Document& doc) const
{
auto val = Message::toJson(doc);
diff --git a/src/rpc/daemon_messages.h b/src/rpc/daemon_messages.h
index adcd7f7c6..685f66843 100644
--- a/src/rpc/daemon_messages.h
+++ b/src/rpc/daemon_messages.h
@@ -89,6 +89,7 @@ BEGIN_RPC_MESSAGE_CLASS(GetBlocksFast);
BEGIN_RPC_MESSAGE_REQUEST;
RPC_MESSAGE_MEMBER(std::list<crypto::hash>, block_ids);
RPC_MESSAGE_MEMBER(uint64_t, start_height);
+ RPC_MESSAGE_MEMBER(bool, prune);
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
RPC_MESSAGE_MEMBER(std::vector<cryptonote::rpc::block_with_transactions>, blocks);
@@ -171,10 +172,11 @@ END_RPC_MESSAGE_CLASS;
BEGIN_RPC_MESSAGE_CLASS(StartMining);
BEGIN_RPC_MESSAGE_REQUEST;
RPC_MESSAGE_MEMBER(std::string, miner_address);
- RPC_MESSAGE_MEMBER(uint64_t, thread_count);
+ RPC_MESSAGE_MEMBER(uint64_t, threads_count);
+ RPC_MESSAGE_MEMBER(bool, do_background_mining);
+ RPC_MESSAGE_MEMBER(bool, ignore_battery);
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(bool, success);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
@@ -182,19 +184,7 @@ BEGIN_RPC_MESSAGE_CLASS(GetInfo);
BEGIN_RPC_MESSAGE_REQUEST;
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(uint64_t, height);
- RPC_MESSAGE_MEMBER(uint64_t, target_height);
- RPC_MESSAGE_MEMBER(uint64_t, difficulty);
- RPC_MESSAGE_MEMBER(uint64_t, target);
- RPC_MESSAGE_MEMBER(uint64_t, tx_count);
- RPC_MESSAGE_MEMBER(uint64_t, tx_pool_size);
- RPC_MESSAGE_MEMBER(uint64_t, alt_blocks_count);
- RPC_MESSAGE_MEMBER(uint64_t, outgoing_connections_count);
- RPC_MESSAGE_MEMBER(uint64_t, incoming_connections_count);
- RPC_MESSAGE_MEMBER(uint64_t, white_peerlist_size);
- RPC_MESSAGE_MEMBER(uint64_t, grey_peerlist_size);
- RPC_MESSAGE_MEMBER(bool, testnet);
- RPC_MESSAGE_MEMBER(crypto::hash, top_block_hash);
+ RPC_MESSAGE_MEMBER(DaemonInfo, info);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
@@ -202,7 +192,6 @@ BEGIN_RPC_MESSAGE_CLASS(StopMining);
BEGIN_RPC_MESSAGE_REQUEST;
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(bool, success);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
@@ -212,8 +201,9 @@ BEGIN_RPC_MESSAGE_CLASS(MiningStatus);
BEGIN_RPC_MESSAGE_RESPONSE;
RPC_MESSAGE_MEMBER(bool, active);
RPC_MESSAGE_MEMBER(uint64_t, speed);
- RPC_MESSAGE_MEMBER(uint64_t, thread_count);
+ RPC_MESSAGE_MEMBER(uint64_t, threads_count);
RPC_MESSAGE_MEMBER(std::string, address);
+ RPC_MESSAGE_MEMBER(bool, is_background_mining_enabled);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
@@ -273,6 +263,15 @@ BEGIN_RPC_MESSAGE_CLASS(GetBlockHeaderByHeight);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
+BEGIN_RPC_MESSAGE_CLASS(GetBlockHeadersByHeight);
+ BEGIN_RPC_MESSAGE_REQUEST;
+ RPC_MESSAGE_MEMBER(std::vector<uint64_t>, heights);
+ END_RPC_MESSAGE_REQUEST;
+ BEGIN_RPC_MESSAGE_RESPONSE;
+ RPC_MESSAGE_MEMBER(std::vector<cryptonote::rpc::BlockHeaderResponse>, headers);
+ END_RPC_MESSAGE_RESPONSE;
+END_RPC_MESSAGE_CLASS;
+
BEGIN_RPC_MESSAGE_CLASS(GetBlock);
BEGIN_RPC_MESSAGE_REQUEST;
END_RPC_MESSAGE_REQUEST;
@@ -334,20 +333,6 @@ BEGIN_RPC_MESSAGE_CLASS(StopDaemon);
END_RPC_MESSAGE_RESPONSE;
END_RPC_MESSAGE_CLASS;
-BEGIN_RPC_MESSAGE_CLASS(FastExit);
- BEGIN_RPC_MESSAGE_REQUEST;
- END_RPC_MESSAGE_REQUEST;
- BEGIN_RPC_MESSAGE_RESPONSE;
- END_RPC_MESSAGE_RESPONSE;
-END_RPC_MESSAGE_CLASS;
-
-BEGIN_RPC_MESSAGE_CLASS(OutPeers);
- BEGIN_RPC_MESSAGE_REQUEST;
- END_RPC_MESSAGE_REQUEST;
- BEGIN_RPC_MESSAGE_RESPONSE;
- END_RPC_MESSAGE_RESPONSE;
-END_RPC_MESSAGE_CLASS;
-
BEGIN_RPC_MESSAGE_CLASS(StartSaveGraph);
BEGIN_RPC_MESSAGE_REQUEST;
END_RPC_MESSAGE_REQUEST;
diff --git a/src/rpc/daemon_rpc_version.h b/src/rpc/daemon_rpc_version.h
index b354b32c2..bb735fe7c 100644
--- a/src/rpc/daemon_rpc_version.h
+++ b/src/rpc/daemon_rpc_version.h
@@ -34,10 +34,10 @@ namespace cryptonote
namespace rpc
{
-static const uint32_t DAEMON_RPC_VERSION_MINOR = 0;
-static const uint32_t DAEMON_RPC_VERSION_MAJOR = 1;
+static const uint32_t DAEMON_RPC_VERSION_ZMQ_MINOR = 0;
+static const uint32_t DAEMON_RPC_VERSION_ZMQ_MAJOR = 1;
-static const uint32_t DAEMON_RPC_VERSION = DAEMON_RPC_VERSION_MINOR + (DAEMON_RPC_VERSION_MAJOR << 16);
+static const uint32_t DAEMON_RPC_VERSION_ZMQ = DAEMON_RPC_VERSION_ZMQ_MINOR + (DAEMON_RPC_VERSION_ZMQ_MAJOR << 16);
} // namespace rpc
diff --git a/src/rpc/message.cpp b/src/rpc/message.cpp
index 7d4499bcf..086820180 100644
--- a/src/rpc/message.cpp
+++ b/src/rpc/message.cpp
@@ -53,7 +53,7 @@ rapidjson::Value Message::toJson(rapidjson::Document& doc) const
val.AddMember("status", rapidjson::StringRef(status.c_str()), al);
val.AddMember("error_details", rapidjson::StringRef(error_details.c_str()), al);
- INSERT_INTO_JSON_OBJECT(val, doc, rpc_version, DAEMON_RPC_VERSION);
+ INSERT_INTO_JSON_OBJECT(val, doc, rpc_version, DAEMON_RPC_VERSION_ZMQ);
return val;
}
diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h
index c2492681d..00f1e0caa 100644
--- a/src/rpc/message_data_structs.h
+++ b/src/rpc/message_data_structs.h
@@ -164,6 +164,26 @@ namespace rpc
uint64_t reward;
};
+ struct DaemonInfo
+ {
+ uint64_t height;
+ uint64_t target_height;
+ uint64_t difficulty;
+ uint64_t target;
+ uint64_t tx_count;
+ uint64_t tx_pool_size;
+ uint64_t alt_blocks_count;
+ uint64_t outgoing_connections_count;
+ uint64_t incoming_connections_count;
+ uint64_t white_peerlist_size;
+ uint64_t grey_peerlist_size;
+ bool testnet;
+ crypto::hash top_block_hash;
+ uint64_t cumulative_difficulty;
+ uint64_t block_size_limit;
+ uint64_t start_time;
+ };
+
} // namespace rpc
} // namespace cryptonote
diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp
index 8e1e47b38..afdff2328 100644
--- a/src/rpc/zmq_server.cpp
+++ b/src/rpc/zmq_server.cpp
@@ -45,10 +45,6 @@ ZmqServer::ZmqServer(RpcHandler& h) :
ZmqServer::~ZmqServer()
{
- for (zmq::socket_t* socket : sockets)
- {
- delete socket;
- }
}
void ZmqServer::serve()
@@ -58,31 +54,36 @@ void ZmqServer::serve()
{
try
{
- for (zmq::socket_t* socket : sockets)
- {
- zmq::message_t message;
+ zmq::message_t message;
- while (socket->recv(&message))
- {
- std::string message_string(reinterpret_cast<const char *>(message.data()), message.size());
+ if (!rep_socket)
+ {
+ throw std::runtime_error("ZMQ RPC server reply socket is null");
+ }
+ while (rep_socket->recv(&message))
+ {
+ std::string message_string(reinterpret_cast<const char *>(message.data()), message.size());
- MDEBUG(std::string("Received RPC request: \"") + message_string + "\"");
+ MDEBUG(std::string("Received RPC request: \"") + message_string + "\"");
- std::string response = handler.handle(message_string);
+ std::string response = handler.handle(message_string);
- zmq::message_t reply(response.size());
- memcpy((void *) reply.data(), response.c_str(), response.size());
+ zmq::message_t reply(response.size());
+ memcpy((void *) reply.data(), response.c_str(), response.size());
- socket->send(reply);
- MDEBUG(std::string("Sent RPC reply: \"") + response + "\"");
- }
+ rep_socket->send(reply);
+ MDEBUG(std::string("Sent RPC reply: \"") + response + "\"");
}
}
- catch (boost::thread_interrupted& e)
+ catch (const boost::thread_interrupted& e)
{
MDEBUG("ZMQ Server thread interrupted.");
}
+ catch (const zmq::error_t& e)
+ {
+ MERROR(std::string("ZMQ error: ") + e.what());
+ }
boost::this_thread::interruption_point();
}
}
@@ -95,26 +96,20 @@ bool ZmqServer::addIPCSocket(std::string address, std::string port)
bool ZmqServer::addTCPSocket(std::string address, std::string port)
{
- zmq::socket_t *new_socket = nullptr;
try
{
std::string addr_prefix("tcp://");
- new_socket = new zmq::socket_t(context, ZMQ_REP);
+ rep_socket.reset(new zmq::socket_t(context, ZMQ_REP));
- new_socket->setsockopt(ZMQ_RCVTIMEO, DEFAULT_RPC_RECV_TIMEOUT_MS);
+ rep_socket->setsockopt(ZMQ_RCVTIMEO, DEFAULT_RPC_RECV_TIMEOUT_MS);
std::string bind_address = addr_prefix + address + std::string(":") + port;
- new_socket->bind(bind_address.c_str());
- sockets.push_back(new_socket);
+ rep_socket->bind(bind_address.c_str());
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
MERROR(std::string("Error creating ZMQ Socket: ") + e.what());
- if (new_socket)
- {
- delete new_socket;
- }
return false;
}
return true;
diff --git a/src/rpc/zmq_server.h b/src/rpc/zmq_server.h
index 964ce2071..c278ff759 100644
--- a/src/rpc/zmq_server.h
+++ b/src/rpc/zmq_server.h
@@ -29,12 +29,11 @@
#pragma once
#include <boost/thread/thread.hpp>
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/variables_map.hpp>
-#include "common/command_line.h"
-
#include <zmq.hpp>
#include <string>
+#include <memory>
+
+#include "common/command_line.h"
#include "rpc_handler.h"
@@ -75,7 +74,7 @@ class ZmqServer
boost::thread run_thread;
- std::vector<zmq::socket_t*> sockets;
+ std::unique_ptr<zmq::socket_t> rep_socket;
};