mirror of
https://github.com/monero-project/monero.git
synced 2025-08-17 12:10:20 -04:00
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
This commit is contained in:
parent
77986023c3
commit
0299cb77ca
15 changed files with 536 additions and 225 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue