diff options
Diffstat (limited to 'src/rpc/core_rpc_server.cpp')
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 984d9d8cd..68df17b9f 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -45,17 +45,35 @@ namespace cryptonote m_net_server.set_threads_prefix("RPC"); bool r = handle_command_line(vm); CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server"); - return epee::http_server_impl_base<core_rpc_server>::init(m_port, m_bind_ip); + return epee::http_server_impl_base<core_rpc_server, connection_context>::init(m_port, m_bind_ip); } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res) + bool core_rpc_server::check_core_ready() { + if(!m_p2p.get_payload_object().is_synchronized()) + { + return false; + } + if(m_p2p.get_payload_object().get_core().get_blockchain_storage().is_storing_blockchain()) + { + return false; + } + return true; + } +#define CHECK_CORE_READY() if(!check_core_ready()){res.status = CORE_RPC_STATUS_BUSY;return true;} + + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_height(const COMMAND_RPC_GET_HEIGHT::request& req, COMMAND_RPC_GET_HEIGHT::response& res, connection_context& cntx) + { + CHECK_CORE_READY(); res.height = m_core.get_current_blockchain_height(); + res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res) + bool core_rpc_server::on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, connection_context& cntx) { + CHECK_CORE_READY(); res.height = m_core.get_current_blockchain_height(); res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block(); res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase @@ -66,21 +84,13 @@ namespace cryptonote res.incoming_connections_count = total_conn - res.outgoing_connections_count; res.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.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_known_block_ids(const COMMAND_RPC_GET_KNOWN_BLOCK_IDS::request& req, COMMAND_RPC_GET_KNOWN_BLOCK_IDS::response& res) - { - std::list<crypto::hash> main, alt, invalid; - m_core.get_all_known_block_ids(main, alt, invalid); - BOOST_FOREACH(crypto::hash &h, main) - res.main.push_back(string_tools::pod_to_hex(h)); - - return true; - } - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res) + bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, connection_context& cntx) { + CHECK_CORE_READY(); std::list<std::pair<block, std::list<transaction> > > bs; if(!m_core.find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT)) { @@ -102,8 +112,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) + bool core_rpc_server::on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res, connection_context& cntx) { + CHECK_CORE_READY(); res.status = "Failed"; if(!m_core.get_random_outs_for_amounts(req, res)) { @@ -115,23 +126,24 @@ namespace cryptonote typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount outs_for_amount; typedef COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry; std::for_each(res.outs.begin(), res.outs.end(), [&](outs_for_amount& ofa) - { - ss << "[" << ofa.amount << "]:"; - CHECK_AND_ASSERT_MES(ofa.outs.size(), ;, "internal error: ofa.outs.size() is empty for amount " << ofa.amount); - std::for_each(ofa.outs.begin(), ofa.outs.end(), [&](out_entry& oe) - { - ss << oe.global_amount_index << " "; - }); - ss << ENDL; - }); + { + ss << "[" << ofa.amount << "]:"; + CHECK_AND_ASSERT_MES(ofa.outs.size(), ;, "internal error: ofa.outs.size() is empty for amount " << ofa.amount); + std::for_each(ofa.outs.begin(), ofa.outs.end(), [&](out_entry& oe) + { + ss << oe.global_amount_index << " "; + }); + ss << ENDL; + }); std::string s = ss.str(); LOG_PRINT_L2("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: " << ENDL << s); res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res) + bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, connection_context& cntx) { + CHECK_CORE_READY(); bool r = m_core.get_tx_outputs_gindexs(req.txid, res.o_indexes); if(!r) { @@ -143,8 +155,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res) + bool core_rpc_server::on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, connection_context& cntx) { + CHECK_CORE_READY(); std::vector<crypto::hash> vh; BOOST_FOREACH(const auto& tx_hex_str, req.txs_hashes) { @@ -184,12 +197,7 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - /*bool core_rpc_server::on_get_outputs(const COMMAND_RPC_GET_OUTPUTS::request& req, COMMAND_RPC_GET_OUTPUTS::response& res) - { - return true; - }*/ - //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res) + bool core_rpc_server::on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, connection_context& cntx) { std::string tx_blob; if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob)) @@ -231,8 +239,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res) + bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx) { + CHECK_CORE_READY(); account_public_address adr; if(!get_account_address_from_str(adr, req.miner_address)) { @@ -249,9 +258,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res) + bool core_rpc_server::on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, connection_context& cntx) { - + CHECK_CORE_READY(); if(!m_core.get_miner().stop()) { res.status = "Failed, mining not stopped"; @@ -261,14 +270,22 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res) + bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, connection_context& cntx) { - res = m_core.get_current_blockchain_height(); + CHECK_CORE_READY(); + res.count = m_core.get_current_blockchain_height(); + res.status = CORE_RPC_STATUS_OK; return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) { + if(!check_core_ready()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy"; + return false; + } if(req.size() != 1) { error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; @@ -300,8 +317,15 @@ namespace cryptonote return 0; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) { + if(!check_core_ready()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy"; + return false; + } + if(req.reserve_size > 255) { error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_RESERVE_SIZE; @@ -359,8 +383,9 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp) + bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) { + CHECK_CORE_READY(); if(req.size()!=1) { error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; |