diff options
Diffstat (limited to 'src/rpc')
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 80 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 2 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 31 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_error_codes.h | 1 | ||||
-rw-r--r-- | src/rpc/message_data_structs.h | 1 |
5 files changed, 113 insertions, 2 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 857370dbb..7db6b7f20 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -193,6 +193,7 @@ namespace cryptonote res.mainnet = m_nettype == MAINNET; res.testnet = m_nettype == TESTNET; res.stagenet = m_nettype == STAGENET; + res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain"; res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1); res.block_size_limit = m_core.get_blockchain_storage().get_current_cumulative_blocksize_limit(); res.block_size_median = m_core.get_blockchain_storage().get_current_cumulative_blocksize_median(); @@ -1209,6 +1210,68 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp) + { + PERF_TIMER(on_generateblocks); + + CHECK_CORE_READY(); + + res.status = CORE_RPC_STATUS_OK; + + if(m_core.get_nettype() != FAKECHAIN) + { + error_resp.code = CORE_RPC_ERROR_CODE_REGTEST_REQUIRED; + error_resp.message = "Regtest required when generating blocks"; + return false; + } + + COMMAND_RPC_GETBLOCKTEMPLATE::request template_req; + COMMAND_RPC_GETBLOCKTEMPLATE::response template_res; + COMMAND_RPC_SUBMITBLOCK::request submit_req; + COMMAND_RPC_SUBMITBLOCK::response submit_res; + + template_req.reserve_size = 1; + template_req.wallet_address = req.wallet_address; + submit_req.push_back(boost::value_initialized<std::string>()); + res.height = m_core.get_blockchain_storage().get_current_blockchain_height(); + + bool r; + + for(size_t i = 0; i < req.amount_of_blocks; i++) + { + r = on_getblocktemplate(template_req, template_res, error_resp); + res.status = template_res.status; + + if (!r) return false; + + blobdata blockblob; + if(!string_tools::parse_hexstr_to_binbuff(template_res.blocktemplate_blob, blockblob)) + { + error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB; + error_resp.message = "Wrong block blob"; + return false; + } + block b = AUTO_VAL_INIT(b); + if(!parse_and_validate_block_from_blob(blockblob, b)) + { + error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB; + error_resp.message = "Wrong block blob"; + return false; + } + miner::find_nonce_for_given_block(b, template_res.difficulty, template_res.height); + + submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b)); + r = on_submitblock(submit_req, submit_res, error_resp); + res.status = submit_res.status; + + if (!r) return false; + + res.height = template_res.height; + } + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ uint64_t core_rpc_server::get_block_reward(const block& blk) { uint64_t reward = 0; @@ -1564,6 +1627,7 @@ namespace cryptonote res.mainnet = m_nettype == MAINNET; res.testnet = m_nettype == TESTNET; res.stagenet = m_nettype == STAGENET; + res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain"; res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1); res.block_size_limit = m_core.get_blockchain_storage().get_current_cumulative_blocksize_limit(); res.block_size_median = m_core.get_blockchain_storage().get_current_cumulative_blocksize_median(); @@ -1774,10 +1838,22 @@ namespace cryptonote PERF_TIMER(on_get_alternate_chains); try { - std::list<std::pair<Blockchain::block_extended_info, uint64_t>> chains = m_core.get_blockchain_storage().get_alternative_chains(); + std::list<std::pair<Blockchain::block_extended_info, std::vector<crypto::hash>>> chains = m_core.get_blockchain_storage().get_alternative_chains(); for (const auto &i: chains) { - res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second, i.first.cumulative_difficulty}); + res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second.size(), i.first.cumulative_difficulty, {}, std::string()}); + res.chains.back().block_hashes.reserve(i.second.size()); + for (const crypto::hash &block_id: i.second) + res.chains.back().block_hashes.push_back(epee::string_tools::pod_to_hex(block_id)); + if (i.first.height < i.second.size()) + { + res.status = "Error finding alternate chain attachment point"; + return true; + } + cryptonote::block main_chain_parent_block; + try { main_chain_parent_block = m_core.get_blockchain_storage().get_db().get_block_from_height(i.first.height - i.second.size()); } + catch (const std::exception &e) { res.status = "Error finding alternate chain attachment point"; return true; } + res.chains.back().main_chain_parent_block = epee::string_tools::pod_to_hex(get_block_hash(main_chain_parent_block)); } res.status = CORE_RPC_STATUS_OK; } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 324f219f8..5e62bc4a8 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -129,6 +129,7 @@ namespace cryptonote MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE) MAP_JON_RPC_WE("submit_block", on_submitblock, COMMAND_RPC_SUBMITBLOCK) MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK) + MAP_JON_RPC_WE_IF("generateblocks", on_generateblocks, COMMAND_RPC_GENERATEBLOCKS, !m_restricted) MAP_JON_RPC_WE("get_last_block_header", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) MAP_JON_RPC_WE("get_block_header_by_hash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) @@ -196,6 +197,7 @@ namespace cryptonote bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp); bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp); bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp); + bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp); 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); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 05690390d..6738171e2 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -955,6 +955,7 @@ namespace cryptonote bool mainnet; bool testnet; bool stagenet; + std::string nettype; std::string top_block_hash; uint64_t cumulative_difficulty; uint64_t block_size_limit; @@ -984,6 +985,7 @@ namespace cryptonote KV_SERIALIZE(mainnet) KV_SERIALIZE(testnet) KV_SERIALIZE(stagenet) + KV_SERIALIZE(nettype) KV_SERIALIZE(top_block_hash) KV_SERIALIZE(cumulative_difficulty) KV_SERIALIZE(block_size_limit) @@ -1151,6 +1153,31 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct COMMAND_RPC_GENERATEBLOCKS + { + struct request + { + uint64_t amount_of_blocks; + std::string wallet_address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_of_blocks) + KV_SERIALIZE(wallet_address) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + uint64_t height; + std::string status; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(height) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; struct block_header_response { @@ -2090,12 +2117,16 @@ namespace cryptonote uint64_t height; uint64_t length; uint64_t difficulty; + std::vector<std::string> block_hashes; + std::string main_chain_parent_block; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(block_hash) KV_SERIALIZE(height) KV_SERIALIZE(length) KV_SERIALIZE(difficulty) + KV_SERIALIZE(block_hashes) + KV_SERIALIZE(main_chain_parent_block) END_KV_SERIALIZE_MAP() }; diff --git a/src/rpc/core_rpc_server_error_codes.h b/src/rpc/core_rpc_server_error_codes.h index 69caaa6a6..5a754749f 100644 --- a/src/rpc/core_rpc_server_error_codes.h +++ b/src/rpc/core_rpc_server_error_codes.h @@ -42,5 +42,6 @@ #define CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE -10 #define CORE_RPC_ERROR_CODE_UNSUPPORTED_RPC -11 #define CORE_RPC_ERROR_CODE_MINING_TO_SUBADDRESS -12 +#define CORE_RPC_ERROR_CODE_REGTEST_REQUIRED -13 diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h index 17ae9629f..fc1b2329d 100644 --- a/src/rpc/message_data_structs.h +++ b/src/rpc/message_data_structs.h @@ -181,6 +181,7 @@ namespace rpc bool mainnet; bool testnet; bool stagenet; + std::string nettype; crypto::hash top_block_hash; uint64_t cumulative_difficulty; uint64_t block_size_limit; |