mirror of
https://github.com/monero-project/monero.git
synced 2025-12-30 06:30:50 -08:00
db: store cumulative rct output distribution in the db for speed
This gets rid of the temporary precalc cache. Also make the RPC able to send data back in binary or JSON, since there can be a lot of data This bumps the LMDB database format to v3, with migration.
This commit is contained in:
@@ -47,7 +47,6 @@ 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
|
||||
@@ -2071,6 +2070,10 @@ namespace cryptonote
|
||||
bool core_rpc_server::on_get_output_distribution(const COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request& req, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response& res, epee::json_rpc::error& error_resp)
|
||||
{
|
||||
PERF_TIMER(on_get_output_distribution);
|
||||
bool r;
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::JON_RPC, "get_output_distribution", req, res, r))
|
||||
return r;
|
||||
|
||||
try
|
||||
{
|
||||
for (uint64_t amount: req.amounts)
|
||||
@@ -2087,38 +2090,17 @@ 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)
|
||||
res.distributions.push_back({amount, d.cached_start_height, req.binary, 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];
|
||||
for (size_t n = distribution.size() - 1; n > 0; --n)
|
||||
distribution[n] -= distribution[n-1];
|
||||
distribution[0] -= d.cached_base;
|
||||
}
|
||||
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, req.to_height, start_height, distribution, base))
|
||||
@@ -2144,14 +2126,14 @@ namespace cryptonote
|
||||
d.cached = true;
|
||||
}
|
||||
|
||||
if (req.cumulative)
|
||||
if (!req.cumulative)
|
||||
{
|
||||
distribution[0] += base;
|
||||
for (size_t n = 1; n < distribution.size(); ++n)
|
||||
distribution[n] += distribution[n-1];
|
||||
for (size_t n = distribution.size() - 1; n > 0; --n)
|
||||
distribution[n] -= distribution[n-1];
|
||||
distribution[0] -= base;
|
||||
}
|
||||
|
||||
res.distributions.push_back({amount, start_height, std::move(distribution), base});
|
||||
res.distributions.push_back({amount, start_height, req.binary, std::move(distribution), base});
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
|
||||
Reference in New Issue
Block a user