Skip to content

Commit

Permalink
Make more functions in RPC server thread safe via db_rtxn_guard
Browse files Browse the repository at this point in the history
- fixed on_getblockhash error resp return when requested height >= blockchain height
  • Loading branch information
j-berman committed Sep 14, 2021
1 parent d26c121 commit 38e1ec1
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,6 @@ namespace cryptonote
}

CHECK_PAYMENT_MIN1(req, res, COST_PER_GET_INFO, false);

// ensures current thread's db reads execute in a single lmdb txn to make function safe from concurrent writes
db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());

const bool restricted = m_restricted && ctx;
Expand Down Expand Up @@ -505,8 +503,6 @@ namespace cryptonote
res.busy_syncing = m_p2p.get_payload_object().is_busy_syncing();
res.synchronized = check_core_ready();

rtxn_guard.stop();

res.status = CORE_RPC_STATUS_OK;
return true;
}
Expand Down Expand Up @@ -554,6 +550,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())
Expand Down Expand Up @@ -685,6 +682,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;
Expand Down Expand Up @@ -1531,6 +1529,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;
Expand All @@ -1555,6 +1554,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;
Expand Down Expand Up @@ -1657,12 +1657,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];
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(blockchain_height - 1);
return false;
}
res = string_tools::pod_to_hex(m_core.get_block_id_by_height(h));
return true;
Expand Down Expand Up @@ -1812,6 +1814,7 @@ namespace cryptonote
return false;
}
}
db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());
uint64_t seed_height;
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))
Expand Down Expand Up @@ -2092,6 +2095,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);
Expand Down Expand Up @@ -2123,6 +2127,7 @@ namespace cryptonote
return r;

CHECK_PAYMENT_MIN1(req, res, COST_PER_BLOCK_HEADER, false);
db_rtxn_guard rtxn_guard(&m_core.get_blockchain_storage().get_db());

const bool restricted = m_restricted && ctx;
if (restricted && req.hashes.size() > RESTRICTED_BLOCK_COUNT)
Expand Down Expand Up @@ -2191,6 +2196,7 @@ 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;

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)
{
Expand Down Expand Up @@ -2251,6 +2257,7 @@ 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;

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)
{
Expand Down Expand Up @@ -2288,6 +2295,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())
Expand Down Expand Up @@ -2614,6 +2622,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)
{
Expand Down Expand Up @@ -2645,6 +2654,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();
Expand Down Expand Up @@ -2945,6 +2955,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);

Expand Down

0 comments on commit 38e1ec1

Please sign in to comment.