|
|
@ -68,6 +68,11 @@ using namespace epee;
|
|
|
|
#define DEFAULT_PAYMENT_DIFFICULTY 1000
|
|
|
|
#define DEFAULT_PAYMENT_DIFFICULTY 1000
|
|
|
|
#define DEFAULT_PAYMENT_CREDITS_PER_HASH 100
|
|
|
|
#define DEFAULT_PAYMENT_CREDITS_PER_HASH 100
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define RESTRICTED_BLOCK_HEADER_RANGE 1000
|
|
|
|
|
|
|
|
#define RESTRICTED_TRANSACTIONS_COUNT 100
|
|
|
|
|
|
|
|
#define RESTRICTED_SPENT_KEY_IMAGES_COUNT 5000
|
|
|
|
|
|
|
|
#define RESTRICTED_BLOCK_COUNT 1000
|
|
|
|
|
|
|
|
|
|
|
|
#define RPC_TRACKER(rpc) \
|
|
|
|
#define RPC_TRACKER(rpc) \
|
|
|
|
PERF_TIMER(rpc); \
|
|
|
|
PERF_TIMER(rpc); \
|
|
|
|
RPCTracker tracker(#rpc, PERF_TIMER_NAME(rpc))
|
|
|
|
RPCTracker tracker(#rpc, PERF_TIMER_NAME(rpc))
|
|
|
@ -639,6 +644,13 @@ namespace cryptonote
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_BY_HEIGHT>(invoke_http_mode::BIN, "/getblocks_by_height.bin", req, res, r))
|
|
|
|
return r;
|
|
|
|
return r;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
|
|
|
|
if (restricted && req.heights.size() > RESTRICTED_BLOCK_COUNT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
res.status = "Too many blocks requested in restricted mode";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res.status = "Failed";
|
|
|
|
res.status = "Failed";
|
|
|
|
res.blocks.clear();
|
|
|
|
res.blocks.clear();
|
|
|
|
res.blocks.reserve(req.heights.size());
|
|
|
|
res.blocks.reserve(req.heights.size());
|
|
|
@ -793,11 +805,17 @@ namespace cryptonote
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_TRANSACTIONS>(invoke_http_mode::JON, "/gettransactions", req, res, ok))
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
const bool request_has_rpc_origin = ctx != NULL;
|
|
|
|
const bool request_has_rpc_origin = ctx != NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (restricted && req.txs_hashes.size() > RESTRICTED_TRANSACTIONS_COUNT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
res.status = "Too many transactions requested in restricted mode";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, req.txs_hashes.size() * COST_PER_TX, false);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<crypto::hash> vh;
|
|
|
|
std::vector<crypto::hash> vh;
|
|
|
|
for(const auto& tx_hex_str: req.txs_hashes)
|
|
|
|
for(const auto& tx_hex_str: req.txs_hashes)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1027,11 +1045,17 @@ namespace cryptonote
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
|
|
|
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_IS_KEY_IMAGE_SPENT>(invoke_http_mode::JON, "/is_key_image_spent", req, res, ok))
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
const bool request_has_rpc_origin = ctx != NULL;
|
|
|
|
const bool request_has_rpc_origin = ctx != NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (restricted && req.key_images.size() > RESTRICTED_SPENT_KEY_IMAGES_COUNT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
res.status = "Too many key images queried in restricted mode";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, req.key_images.size() * COST_PER_KEY_IMAGE, false);
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<crypto::key_image> key_images;
|
|
|
|
std::vector<crypto::key_image> key_images;
|
|
|
|
for(const auto& ki_hex_str: req.key_images)
|
|
|
|
for(const auto& ki_hex_str: req.key_images)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -2034,6 +2058,14 @@ namespace cryptonote
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
|
|
|
|
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
|
|
|
|
|
|
|
error_resp.message = "Too many block headers requested in restricted mode";
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
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;
|
|
|
|
crypto::hash block_hash;
|
|
|
|
bool hash_parsed = parse_hash256(hash, block_hash);
|
|
|
|
bool hash_parsed = parse_hash256(hash, block_hash);
|
|
|
@ -2069,7 +2101,6 @@ namespace cryptonote
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
|
|
|
|
if (!req.hash.empty())
|
|
|
|
if (!req.hash.empty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!get(req.hash, req.fill_pow_hash, res.block_header, restricted, error_resp))
|
|
|
|
if (!get(req.hash, req.fill_pow_hash, res.block_header, restricted, error_resp))
|
|
|
@ -2101,6 +2132,14 @@ namespace cryptonote
|
|
|
|
error_resp.message = "Invalid start/end heights.";
|
|
|
|
error_resp.message = "Invalid start/end heights.";
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
|
|
|
|
if (restricted && req.end_height - req.start_height > RESTRICTED_BLOCK_HEADER_RANGE)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
|
|
|
|
|
|
|
error_resp.message = "Too many block headers requested.";
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
|
|
|
|
CHECK_PAYMENT_MIN1(req, res, (req.end_height - req.start_height + 1) * COST_PER_BLOCK_HEADER, false);
|
|
|
|
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
|
|
|
|
for (uint64_t h = req.start_height; h <= req.end_height; ++h)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -2127,7 +2166,6 @@ namespace cryptonote
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res.headers.push_back(block_header_response());
|
|
|
|
res.headers.push_back(block_header_response());
|
|
|
|
const bool restricted = m_restricted && ctx;
|
|
|
|
|
|
|
|
bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash && !restricted);
|
|
|
|
bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash && !restricted);
|
|
|
|
if (!response_filled)
|
|
|
|
if (!response_filled)
|
|
|
|
{
|
|
|
|
{
|
|
|
|