aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/core_rpc_server.cpp107
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h26
-rw-r--r--src/rpc/rpc_args.cpp6
4 files changed, 118 insertions, 23 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index da36f3c64..40b1b1000 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -478,6 +478,7 @@ namespace cryptonote
}
CHECK_PAYMENT_MIN1(req, res, COST_PER_GET_INFO, false);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
const bool restricted = m_restricted && ctx;
@@ -534,6 +535,7 @@ namespace cryptonote
res.version = restricted ? "" : MONERO_VERSION_FULL;
res.synchronized = check_core_ready();
res.busy_syncing = m_p2p.get_payload_object().is_busy_syncing();
+ res.restricted = restricted;
res.status = CORE_RPC_STATUS_OK;
return true;
@@ -582,6 +584,7 @@ namespace cryptonote
}
CHECK_PAYMENT(req, res, 1);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
// quick check for noop
if (!req.block_ids.empty())
@@ -592,7 +595,7 @@ namespace cryptonote
if (last_block_hash == req.block_ids.front())
{
res.start_height = 0;
- res.current_height = m_core.get_current_blockchain_height();
+ res.current_height = last_block_height + 1;
res.status = CORE_RPC_STATUS_OK;
return true;
}
@@ -713,6 +716,7 @@ namespace cryptonote
res.blocks.clear();
res.blocks.reserve(req.heights.size());
CHECK_PAYMENT_MIN1(req, res, req.heights.size() * COST_PER_BLOCK, false);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
for (uint64_t height : req.heights)
{
block blk;
@@ -1574,6 +1578,7 @@ namespace cryptonote
return r;
CHECK_PAYMENT(req, res, 1);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
const bool restricted = m_restricted && ctx;
const bool request_has_rpc_origin = ctx != NULL;
@@ -1598,6 +1603,7 @@ namespace cryptonote
return r;
CHECK_PAYMENT(req, res, 1);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
const bool restricted = m_restricted && ctx;
const bool request_has_rpc_origin = ctx != NULL;
@@ -1700,11 +1706,14 @@ namespace cryptonote
error_resp.message = "Wrong parameters, expected height";
return false;
}
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
uint64_t h = req[0];
- if(m_core.get_current_blockchain_height() <= h)
+ uint64_t blockchain_height = m_core.get_current_blockchain_height();
+ if(blockchain_height <= h)
{
error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
- error_resp.message = std::string("Requested block height: ") + std::to_string(h) + " greater than current top block height: " + std::to_string(m_core.get_current_blockchain_height() - 1);
+ error_resp.message = std::string("Requested block height: ") + std::to_string(h) + " greater than current top block height: " + std::to_string(blockchain_height - 1);
+ return false;
}
res = string_tools::pod_to_hex(m_core.get_block_id_by_height(h));
return true;
@@ -1854,6 +1863,7 @@ namespace cryptonote
return false;
}
}
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
crypto::hash seed_hash, next_seed_hash;
if (!get_block_template(info.address, req.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, b, res.seed_height, seed_hash, next_seed_hash, error_resp))
return false;
@@ -1912,6 +1922,43 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_calcpow(const COMMAND_RPC_CALCPOW::request& req, COMMAND_RPC_CALCPOW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
+ {
+ RPC_TRACKER(calcpow);
+
+ blobdata blockblob;
+ if(!string_tools::parse_hexstr_to_binbuff(req.block_blob, blockblob))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
+ error_resp.message = "Wrong block blob";
+ return false;
+ }
+ if(!m_core.check_incoming_block_size(blockblob))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE;
+ error_resp.message = "Block blob size is too big, rejecting block";
+ return false;
+ }
+ crypto::hash seed_hash, pow_hash;
+ std::string buf;
+ if(req.seed_hash.size())
+ {
+ if (!string_tools::parse_hexstr_to_binbuff(req.seed_hash, buf) ||
+ buf.size() != sizeof(crypto::hash))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ error_resp.message = "Wrong seed hash";
+ return false;
+ }
+ buf.copy(reinterpret_cast<char *>(&seed_hash), sizeof(crypto::hash));
+ }
+
+ cryptonote::get_block_longhash(&(m_core.get_blockchain_storage()), blockblob, pow_hash, req.height,
+ req.major_version, req.seed_hash.size() ? &seed_hash : NULL, 0);
+ res = string_tools::pod_to_hex(pow_hash);
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_add_aux_pow(const COMMAND_RPC_ADD_AUX_POW::request& req, COMMAND_RPC_ADD_AUX_POW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
RPC_TRACKER(add_aux_pow);
@@ -2290,6 +2337,7 @@ namespace cryptonote
CHECK_CORE_READY();
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
uint64_t last_block_height;
crypto::hash last_block_hash;
m_core.get_blockchain_top(last_block_height, last_block_hash);
@@ -2330,6 +2378,8 @@ namespace cryptonote
return false;
}
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
+
auto get = [this](const std::string &hash, bool fill_pow_hash, block_header_response &block_header, bool restricted, epee::json_rpc::error& error_resp) -> bool {
crypto::hash block_hash;
bool hash_parsed = parse_hash256(hash, block_hash);
@@ -2389,13 +2439,6 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADERS_RANGE>(invoke_http_mode::JON_RPC, "getblockheadersrange", req, res, r))
return r;
- const uint64_t bc_height = m_core.get_current_blockchain_height();
- if (req.start_height >= bc_height || req.end_height >= bc_height || req.start_height > req.end_height)
- {
- error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
- error_resp.message = "Invalid start/end heights.";
- return false;
- }
const bool restricted = m_restricted && ctx;
if (restricted && req.end_height - req.start_height > RESTRICTED_BLOCK_HEADER_RANGE)
{
@@ -2405,6 +2448,16 @@ namespace cryptonote
}
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
+
+ const uint64_t bc_height = m_core.get_current_blockchain_height();
+ if (req.start_height >= bc_height || req.end_height >= bc_height || req.start_height > req.end_height)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
+ error_resp.message = "Invalid start/end heights.";
+ return false;
+ }
+
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
{
crypto::hash block_hash = m_core.get_block_id_by_height(h);
@@ -2449,10 +2502,12 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT>(invoke_http_mode::JON_RPC, "getblockheaderbyheight", req, res, r))
return r;
- if(m_core.get_current_blockchain_height() <= req.height)
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
+ uint64_t blockchain_height = m_core.get_current_blockchain_height();
+ if(blockchain_height <= req.height)
{
error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
- error_resp.message = std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(m_core.get_current_blockchain_height() - 1);
+ error_resp.message = std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(blockchain_height - 1);
return false;
}
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
@@ -2485,6 +2540,7 @@ namespace cryptonote
return r;
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK, false);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
crypto::hash block_hash;
if (!req.hash.empty())
@@ -2499,10 +2555,11 @@ namespace cryptonote
}
else
{
- if(m_core.get_current_blockchain_height() <= req.height)
+ uint64_t blockchain_height = m_core.get_current_blockchain_height();
+ if(blockchain_height <= req.height)
{
error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;
- error_resp.message = std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(m_core.get_current_blockchain_height() - 1);
+ error_resp.message = std::string("Requested block height: ") + std::to_string(req.height) + " greater than current top block height: " + std::to_string(blockchain_height - 1);
return false;
}
block_hash = m_core.get_block_id_by_height(req.height);
@@ -2810,6 +2867,7 @@ namespace cryptonote
bool core_rpc_server::on_get_coinbase_tx_sum(const COMMAND_RPC_GET_COINBASE_TX_SUM::request& req, COMMAND_RPC_GET_COINBASE_TX_SUM::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
RPC_TRACKER(get_coinbase_tx_sum);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
const uint64_t bc_height = m_core.get_current_blockchain_height();
if (req.height >= bc_height || req.count > bc_height)
{
@@ -2841,6 +2899,7 @@ namespace cryptonote
bool core_rpc_server::on_get_alternate_chains(const COMMAND_RPC_GET_ALTERNATE_CHAINS::request& req, COMMAND_RPC_GET_ALTERNATE_CHAINS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
RPC_TRACKER(get_alternate_chains);
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
try
{
std::vector<std::pair<Blockchain::block_extended_info, std::vector<crypto::hash>>> chains = m_core.get_blockchain_storage().get_alternative_chains();
@@ -2898,7 +2957,7 @@ namespace cryptonote
{
if (req.limit_down != -1)
{
- res.status = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ res.status = "Invalid parameter";
return true;
}
epee::net_utils::connection_basic::set_rate_down_limit(nodetool::default_limit_down);
@@ -2912,7 +2971,7 @@ namespace cryptonote
{
if (req.limit_up != -1)
{
- res.status = CORE_RPC_ERROR_CODE_WRONG_PARAM;
+ res.status = "Invalid parameter";
return true;
}
epee::net_utils::connection_basic::set_rate_up_limit(nodetool::default_limit_up);
@@ -3143,6 +3202,7 @@ namespace cryptonote
bool r;
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG>(invoke_http_mode::JON_RPC, "get_txpool_backlog", req, res, r))
return r;
+ db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
size_t n_txes = m_core.get_pool_transactions_count();
CHECK_PAYMENT_MIN1(req, res, COST_PER_TX_POOL_STATS * n_txes, false);
@@ -3164,6 +3224,14 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::JON_RPC, "get_output_distribution", req, res, r))
return r;
+ const bool restricted = m_restricted && ctx;
+ if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
+ error_resp.message = "Restricted RPC can only get output distribution for rct outputs. Use your own node.";
+ return false;
+ }
+
size_t n_0 = 0, n_non0 = 0;
for (uint64_t amount: req.amounts)
if (amount) ++n_non0; else ++n_0;
@@ -3205,6 +3273,13 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r))
return r;
+ const bool restricted = m_restricted && ctx;
+ if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
+ {
+ res.status = "Restricted RPC can only get output distribution for rct outputs. Use your own node.";
+ return false;
+ }
+
size_t n_0 = 0, n_non0 = 0;
for (uint64_t amount: req.amounts)
if (amount) ++n_non0; else ++n_0;
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 84b14383a..664af3686 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -149,6 +149,7 @@ namespace cryptonote
MAP_JON_RPC_WE("get_block_template", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE)
MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE)
MAP_JON_RPC_WE("get_miner_data", on_getminerdata, COMMAND_RPC_GETMINERDATA)
+ MAP_JON_RPC_WE_IF("calc_pow", on_calcpow, COMMAND_RPC_CALCPOW, !m_restricted)
MAP_JON_RPC_WE("add_aux_pow", on_add_aux_pow, COMMAND_RPC_ADD_AUX_POW)
MAP_JON_RPC_WE("submit_block", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
@@ -231,6 +232,7 @@ namespace cryptonote
bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_getminerdata(const COMMAND_RPC_GETMINERDATA::request& req, COMMAND_RPC_GETMINERDATA::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
+ bool on_calcpow(const COMMAND_RPC_CALCPOW::request& req, COMMAND_RPC_CALCPOW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_add_aux_pow(const COMMAND_RPC_ADD_AUX_POW::request& req, COMMAND_RPC_ADD_AUX_POW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 1dbfc83a7..d25196841 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -88,7 +88,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 3
-#define CORE_RPC_VERSION_MINOR 8
+#define CORE_RPC_VERSION_MINOR 10
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@@ -689,6 +689,7 @@ namespace cryptonote
bool busy_syncing;
std::string version;
bool synchronized;
+ bool restricted;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_access_response_base)
@@ -730,6 +731,7 @@ namespace cryptonote
KV_SERIALIZE(busy_syncing)
KV_SERIALIZE(version)
KV_SERIALIZE(synchronized)
+ KV_SERIALIZE(restricted)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
@@ -990,6 +992,28 @@ namespace cryptonote
typedef epee::misc_utils::struct_init<response_t> response;
};
+ struct COMMAND_RPC_CALCPOW
+ {
+ struct request_t: public rpc_request_base
+ {
+ uint8_t major_version;
+ uint64_t height;
+ blobdata block_blob;
+ std::string seed_hash;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE_PARENT(rpc_request_base)
+ KV_SERIALIZE(major_version)
+ KV_SERIALIZE(height)
+ KV_SERIALIZE(block_blob)
+ KV_SERIALIZE(seed_hash)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ typedef std::string response;
+ };
+
struct COMMAND_RPC_ADD_AUX_POW
{
struct aux_pow_t
diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp
index 0966fb6d2..b2d019ae7 100644
--- a/src/rpc/rpc_args.cpp
+++ b/src/rpc/rpc_args.cpp
@@ -247,12 +247,6 @@ namespace cryptonote
auto access_control_origins_input = command_line::get_arg(vm, arg.rpc_access_control_origins);
if (!access_control_origins_input.empty())
{
- if (!config.login)
- {
- LOG_ERROR(arg.rpc_access_control_origins.name << tr(" requires RPC server password --") << arg.rpc_login.name << tr(" cannot be empty"));
- return boost::none;
- }
-
std::vector<std::string> access_control_origins;
boost::split(access_control_origins, access_control_origins_input, boost::is_any_of(","));
std::for_each(access_control_origins.begin(), access_control_origins.end(), std::bind(&boost::trim<std::string>, std::placeholders::_1, std::locale::classic()));