aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/core_rpc_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc/core_rpc_server.cpp')
-rw-r--r--src/rpc/core_rpc_server.cpp76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 3645c494e..dc7b6b30f 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -47,6 +47,7 @@ using namespace epee;
#include "rpc/rpc_args.h"
#include "core_rpc_server_error_codes.h"
#include "p2p/net_node.h"
+#include "get_output_distribution_cache.h"
#include "version.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -218,18 +219,6 @@ namespace cryptonote
return ss.str();
}
//------------------------------------------------------------------------------------------------------------------------------
- static cryptonote::blobdata get_pruned_tx_blob(const cryptonote::blobdata &blobdata)
- {
- cryptonote::transaction tx;
-
- if (!cryptonote::parse_and_validate_tx_from_blob(blobdata, tx))
- {
- MERROR("Failed to parse and validate tx from blob");
- return cryptonote::blobdata();
- }
- return get_pruned_tx_blob(tx);
- }
- //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res)
{
PERF_TIMER(on_get_blocks);
@@ -239,7 +228,7 @@ namespace cryptonote
std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > > bs;
- if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
+ if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
{
res.status = "Failed";
return false;
@@ -271,10 +260,7 @@ namespace cryptonote
for (std::list<cryptonote::blobdata>::iterator i = bd.second.begin(); i != bd.second.end(); ++i)
{
unpruned_size += i->size();
- if (req.prune)
- res.blocks.back().txs.push_back(get_pruned_tx_blob(std::move(*i)));
- else
- res.blocks.back().txs.push_back(std::move(*i));
+ res.blocks.back().txs.push_back(std::move(*i));
i->clear();
i->shrink_to_fit();
pruned_size += res.blocks.back().txs.back().size();
@@ -1233,7 +1219,7 @@ namespace cryptonote
return reward;
}
//------------------------------------------------------------------------------------------------------------------------------
- bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response)
+ bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash)
{
PERF_TIMER(fill_block_header_response);
response.major_version = blk.major_version;
@@ -1249,6 +1235,7 @@ namespace cryptonote
response.reward = get_block_reward(blk);
response.block_size = m_core.get_blockchain_storage().get_db().get_block_size(height);
response.num_txes = blk.tx_hashes.size();
+ response.pow_hash = fill_pow_hash ? string_tools::pod_to_hex(get_block_longhash(blk, height)) : "";
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
@@ -1338,7 +1325,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get last block.";
return false;
}
- bool response_filled = fill_block_header_response(last_block, false, last_block_height, last_block_hash, res.block_header);
+ bool response_filled = fill_block_header_response(last_block, false, last_block_height, last_block_hash, res.block_header, req.fill_pow_hash);
if (!response_filled)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
@@ -1379,7 +1366,7 @@ namespace cryptonote
return false;
}
uint64_t block_height = boost::get<txin_gen>(blk.miner_tx.vin.front()).height;
- bool response_filled = fill_block_header_response(blk, orphan, block_height, block_hash, res.block_header);
+ bool response_filled = fill_block_header_response(blk, orphan, block_height, block_hash, res.block_header, req.fill_pow_hash);
if (!response_filled)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
@@ -1428,7 +1415,7 @@ namespace cryptonote
return false;
}
res.headers.push_back(block_header_response());
- bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back());
+ bool response_filled = fill_block_header_response(blk, false, block_height, block_hash, res.headers.back(), req.fill_pow_hash);
if (!response_filled)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
@@ -1461,7 +1448,7 @@ namespace cryptonote
error_resp.message = "Internal error: can't get block by height. Height = " + std::to_string(req.height) + '.';
return false;
}
- bool response_filled = fill_block_header_response(blk, false, req.height, block_hash, res.block_header);
+ bool response_filled = fill_block_header_response(blk, false, req.height, block_hash, res.block_header, req.fill_pow_hash);
if (!response_filled)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
@@ -1515,7 +1502,7 @@ namespace cryptonote
return false;
}
uint64_t block_height = boost::get<txin_gen>(blk.miner_tx.vin.front()).height;
- bool response_filled = fill_block_header_response(blk, orphan, block_height, block_hash, res.block_header);
+ bool response_filled = fill_block_header_response(blk, orphan, block_height, block_hash, res.block_header, req.fill_pow_hash);
if (!response_filled)
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
@@ -2100,12 +2087,40 @@ namespace cryptonote
if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height)
{
res.distributions.push_back({amount, d.cached_start_height, d.cached_distribution, d.cached_base});
+ if (req.cumulative)
+ {
+ auto &distribution = res.distributions.back().distribution;
+ distribution[0] += d.cached_base;
+ for (size_t n = 1; n < distribution.size(); ++n)
+ distribution[n] += distribution[n-1];
+ }
continue;
}
+ // this is a slow operation, so we have precomputed caches of common cases
+ bool found = false;
+ for (const auto &slot: get_output_distribution_cache)
+ {
+ if (slot.amount == amount && slot.from_height == req.from_height && slot.to_height == req.to_height)
+ {
+ res.distributions.push_back({amount, slot.start_height, slot.distribution, slot.base});
+ found = true;
+ if (req.cumulative)
+ {
+ auto &distribution = res.distributions.back().distribution;
+ distribution[0] += slot.base;
+ for (size_t n = 1; n < distribution.size(); ++n)
+ distribution[n] += distribution[n-1];
+ }
+ break;
+ }
+ }
+ if (found)
+ continue;
+
std::vector<uint64_t> distribution;
uint64_t start_height, base;
- if (!m_core.get_output_distribution(amount, req.from_height, start_height, distribution, base))
+ if (!m_core.get_output_distribution(amount, req.from_height, req.to_height, start_height, distribution, base))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Failed to get rct distribution";
@@ -2117,12 +2132,6 @@ namespace cryptonote
if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size())
distribution.resize(req.to_height - offset + 1);
}
- if (req.cumulative)
- {
- distribution[0] += base;
- for (size_t n = 1; n < distribution.size(); ++n)
- distribution[n] += distribution[n-1];
- }
if (amount == 0)
{
@@ -2134,6 +2143,13 @@ namespace cryptonote
d.cached = true;
}
+ if (req.cumulative)
+ {
+ distribution[0] += base;
+ for (size_t n = 1; n < distribution.size(); ++n)
+ distribution[n] += distribution[n-1];
+ }
+
res.distributions.push_back({amount, start_height, std::move(distribution), base});
}
}