Add constraints/limits to async rest responses (#229)

This commit is contained in:
Lee *!* Clagett
2026-03-18 15:50:28 -04:00
committed by Lee *!* Clagett
parent 6b3ec7c1b7
commit 97e0161cfd
4 changed files with 32 additions and 1 deletions
+10
View File
@@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include "cryptonote_config.h"
namespace lws
@@ -7,5 +8,14 @@ namespace lws
namespace config
{
extern cryptonote::network_type network;
//! Max queued clients when waiting for cacheable daemon response
constexpr const std::size_t daemon_wait_queue_max = 25000;
//! Max queued clients for `get_random_outs`
constexpr const std::size_t get_random_outs_max = 10000;
//! Max memory allowed for `submit_raw_tx` buffering
constexpr const std::size_t submit_tx_max = 100 * 1024 * 1024;
}
}
+3
View File
@@ -91,6 +91,8 @@ namespace lws
return "Invalid subaddress range provided";
case error::json_rpc:
return "Error returned by JSON-RPC server";
case error::load:
return "Server load limits have been reached";
case error::exchange_rates_old:
return "Exchange rates are older than cache interval";
case error::max_subaddresses:
@@ -125,6 +127,7 @@ namespace lws
case error::bad_view_key:
return std::errc::bad_address;
case error::daemon_timeout:
case error::load:
return std::errc::timed_out;
case error::exceeded_blockchain_buffer:
return std::errc::no_buffer_space;
+1
View File
@@ -60,6 +60,7 @@ namespace lws
http_server, //!< HTTP server failure (init or run)
invalid_range, //!< Invalid subaddress range provided
json_rpc, //!< Error returned by JSON-RPC server
load, //!< Server load limits reached
max_subaddresses, //!< Max subaddresses exceeded
not_enough_mixin, //!< Not enough outputs to meet mixin count
not_enough_amount, //!< Not enough outputs to meet amount
+18 -1
View File
@@ -364,6 +364,9 @@ namespace lws
auto active = cache.status.lock();
if (active)
{
if (config::daemon_wait_queue_max < active->resumers.size())
return {error::load};
active->resumers.push_back(std::move(resume));
return async_ready();
}
@@ -757,6 +760,9 @@ namespace lws
auto active = cache.status.lock();
if (active)
{
if (config::get_random_outs_max < active->resumers.size())
return {error::load};
active->resumers.emplace_back(std::move(req), std::move(resume));
return success();
}
@@ -1193,6 +1199,9 @@ namespace lws
auto active = cache.status.lock();
if (active)
{
if (config::daemon_wait_queue_max < active->resumers.size())
return {error::load};
active->resumers.emplace_back(std::move(req), std::move(resume));
return async_ready();
}
@@ -1587,6 +1596,7 @@ namespace lws
boost::asio::steady_timer timer;
boost::asio::io_context::strand strand;
std::deque<std::pair<epee::byte_slice, std::function<async_complete>>> resumers;
std::size_t outstanding;
frame(rest_server_data& parent, net::zmq::async_client client)
: parent(std::addressof(parent)),
@@ -1594,7 +1604,8 @@ namespace lws
client(std::move(client)),
timer(parent.io),
strand(parent.io),
resumers()
resumers(),
outstanding(0)
{}
};
@@ -1620,6 +1631,10 @@ namespace lws
auto active = cache.status.lock();
if (active)
{
if (std::numeric_limits<std::size_t>::max() - msg.size() < active->outstanding || config::submit_tx_max < msg.size() + active->outstanding)
return {error::load};
active->outstanding += msg.size();
active->resumers.emplace_back(std::move(msg), std::move(resume));
return success();
}
@@ -1709,6 +1724,7 @@ namespace lws
return;
}
next = std::move(self_->resumers.front().first);
self_->outstanding -= std::min(self_->outstanding, next.size());
}
set_timeout(std::chrono::seconds{10}, false);
@@ -1751,6 +1767,7 @@ namespace lws
active = std::make_shared<frame>(*data.global, std::move(*client));
cache.status = active;
active->outstanding += msg.size();
active->resumers.emplace_back(std::move(msg), std::move(resume));
lock.unlock();