Make get_sn_state_changes admin-only

This call can make the node do a full tx scan for state change
transactions, which can be expensive.  It is currently only used in the
oxend CLI interface, so seems fine to make admin-restricted.
This commit is contained in:
Jason Rhinelander 2022-12-16 19:22:21 -04:00
parent 2c7a4ab841
commit 3179a97b32
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262
4 changed files with 23 additions and 21 deletions

View File

@ -42,13 +42,23 @@ namespace daemonize {
namespace log = oxen::log;
static auto logcat = log::Cat("daemon");
template <typename T>
constexpr bool is_std_optional = false;
template <typename T>
inline constexpr bool is_std_optional<std::optional<T>> = true;
// Consumes an argument from the given list, if present, parsing it into `var`.
// Returns false upon parse failure, true otherwise.
template <typename T>
static bool parse_if_present(std::forward_list<std::string> &list, T &var, const char *name)
static bool parse_if_present(std::forward_list<std::string>& list, T& var, const char* name)
{
if (list.empty()) return true;
if (epee::string_tools::get_xtype_from_string(var, list.front()))
bool good = false;
if constexpr (is_std_optional<T>)
good = epee::string_tools::get_xtype_from_string(var.emplace(), list.front());
else
good = epee::string_tools::get_xtype_from_string(var, list.front());
if (good)
{
list.pop_front();
return true;

View File

@ -2760,22 +2760,15 @@ namespace cryptonote::rpc {
std::vector<block_pair_t> blocks;
const auto& db = m_core.get_blockchain_storage();
const uint64_t current_height = db.get_current_blockchain_height();
uint64_t end_height;
uint64_t start_height = get_sn_state_changes.request.start_height;
if (get_sn_state_changes.request.end_height == GET_SN_STATE_CHANGES::HEIGHT_SENTINEL_VALUE) {
// current height is the block being mined, so exclude it from the results
end_height = current_height - 1;
} else {
end_height = get_sn_state_changes.request.end_height;
}
auto start_height = get_sn_state_changes.request.start_height;
auto end_height = get_sn_state_changes.request.end_height.value_or(db.get_current_blockchain_height() - 1);
if (end_height < start_height)
throw rpc_error{ERROR_WRONG_PARAM, "The provided end_height needs to be higher than start_height"};
if (!db.get_blocks(start_height, end_height - start_height + 1, blocks))
throw rpc_error{ERROR_INTERNAL, "Could not query block at requested height: " + std::to_string(start_height)};
throw rpc_error{ERROR_INTERNAL, "Could not query blocks at requested height {}"_format(start_height)};
get_sn_state_changes.response["start_height"] = start_height;
get_sn_state_changes.response["end_height"] = end_height;

View File

@ -278,7 +278,7 @@ namespace cryptonote::rpc {
void parse_request(GET_SN_STATE_CHANGES& get_sn_state_changes, rpc_input in) {
get_values(in,
"end_height", get_sn_state_changes.request.end_height,
"start_height", get_sn_state_changes.request.start_height);
"start_height", required{get_sn_state_changes.request.start_height});
}
void parse_request(REPORT_PEER_STATUS& report_peer_status, rpc_input in) {

View File

@ -1988,15 +1988,15 @@ namespace cryptonote::rpc {
} request;
};
/// Query hardcoded/service node checkpoints stored for the blockchain. Omit all arguments to
/// retrieve the latest "count" checkpoints.
/// Query recent service node state changes processed on the blockchain.
///
/// Inputs:
///
/// - \p start_height The starting block's height.
/// - \p end_height The ending block's height.
/// - \p start_height Returns counts starting from this block height. Required.
/// - \p end_height Optional: returns count ending at this block height; if omitted, counts to the
/// current height.
///
/// Output values available from a public RPC endpoint:
/// Output values available from a private/admin RPC endpoint:
///
/// - \p status Generic RPC error code. "OK" is the success value.
/// - \p total_deregister
@ -2006,15 +2006,14 @@ namespace cryptonote::rpc {
/// - \p total_unlock
/// - \p start_height
/// - \p end_height
struct GET_SN_STATE_CHANGES : PUBLIC
struct GET_SN_STATE_CHANGES : RPC_COMMAND
{
static constexpr auto names() { return NAMES("get_service_nodes_state_changes"); }
static constexpr uint64_t HEIGHT_SENTINEL_VALUE = std::numeric_limits<uint64_t>::max() - 1;
struct request_parameters
{
uint64_t start_height;
uint64_t end_height; // Optional: If omitted, the tally runs until the current block
std::optional<uint64_t> end_height;
} request;
};