validation: Don't error if maxsigcachesize exceeds uint32::max

Instead clamp it to uint32::max if it exceeds it.

Co-authored-by: Anthony Towns <aj@erisian.com.au>
This commit is contained in:
TheCharlatan 2024-05-20 22:32:32 +02:00
parent d2c8d161b4
commit ab14d1d6a4
No known key found for this signature in database
GPG key ID: 9B79B45691DB4173
5 changed files with 11 additions and 24 deletions

View file

@ -14,7 +14,6 @@
#include <cstring> #include <cstring>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <optional>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -360,16 +359,15 @@ public:
* structure * structure
* @returns A pair of the maximum number of elements storable (see setup() * @returns A pair of the maximum number of elements storable (see setup()
* documentation for more detail) and the approximate total size of these * documentation for more detail) and the approximate total size of these
* elements in bytes or std::nullopt if the size requested is too large. * elements in bytes.
*/ */
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t bytes) std::pair<uint32_t, size_t> setup_bytes(size_t bytes)
{ {
size_t requested_num_elems = bytes / sizeof(Element); uint32_t requested_num_elems(std::min<size_t>(
if (std::numeric_limits<uint32_t>::max() < requested_num_elems) { bytes / sizeof(Element),
return std::nullopt; std::numeric_limits<uint32_t>::max()));
}
auto num_elems = setup(bytes/sizeof(Element)); auto num_elems = setup(requested_num_elems);
size_t approx_size_bytes = num_elems * sizeof(Element); size_t approx_size_bytes = num_elems * sizeof(Element);
return std::make_pair(num_elems, approx_size_bytes); return std::make_pair(num_elems, approx_size_bytes);

View file

@ -1156,11 +1156,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
ValidationCacheSizes validation_cache_sizes{}; ValidationCacheSizes validation_cache_sizes{};
ApplyArgsManOptions(args, validation_cache_sizes); ApplyArgsManOptions(args, validation_cache_sizes);
if (!InitSignatureCache(validation_cache_sizes.signature_cache_bytes) (void)InitSignatureCache(validation_cache_sizes.signature_cache_bytes);
|| !InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes)) (void)InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes);
{
return InitError(strprintf(_("Unable to allocate memory for -maxsigcachesize: '%s' MiB"), args.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_BYTES >> 20)));
}
assert(!node.scheduler); assert(!node.scheduler);
node.scheduler = std::make_unique<CScheduler>(); node.scheduler = std::make_unique<CScheduler>();

View file

@ -15,7 +15,6 @@
#include <algorithm> #include <algorithm>
#include <mutex> #include <mutex>
#include <optional>
#include <shared_mutex> #include <shared_mutex>
#include <vector> #include <vector>
@ -77,7 +76,7 @@ public:
std::unique_lock<std::shared_mutex> lock(cs_sigcache); std::unique_lock<std::shared_mutex> lock(cs_sigcache);
setValid.insert(entry); setValid.insert(entry);
} }
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t n) std::pair<uint32_t, size_t> setup_bytes(size_t n)
{ {
return setValid.setup_bytes(n); return setValid.setup_bytes(n);
} }
@ -96,10 +95,7 @@ static CSignatureCache signatureCache;
// signatureCache. // signatureCache.
bool InitSignatureCache(size_t max_size_bytes) bool InitSignatureCache(size_t max_size_bytes)
{ {
auto setup_results = signatureCache.setup_bytes(max_size_bytes); const auto [num_elems, approx_size_bytes] = signatureCache.setup_bytes(max_size_bytes);
if (!setup_results) return false;
const auto [num_elems, approx_size_bytes] = *setup_results;
LogPrintf("Using %zu MiB out of %zu MiB requested for signature cache, able to store %zu elements\n", LogPrintf("Using %zu MiB out of %zu MiB requested for signature cache, able to store %zu elements\n",
approx_size_bytes >> 20, max_size_bytes >> 20, num_elems); approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
return true; return true;

View file

@ -10,7 +10,6 @@
#include <span.h> #include <span.h>
#include <util/hasher.h> #include <util/hasher.h>
#include <optional>
#include <vector> #include <vector>
// DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit // DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit

View file

@ -2100,10 +2100,7 @@ bool InitScriptExecutionCache(size_t max_size_bytes)
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32); g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32); g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
auto setup_results = g_scriptExecutionCache.setup_bytes(max_size_bytes); const auto [num_elems, approx_size_bytes] = g_scriptExecutionCache.setup_bytes(max_size_bytes);
if (!setup_results) return false;
const auto [num_elems, approx_size_bytes] = *setup_results;
LogPrintf("Using %zu MiB out of %zu MiB requested for script execution cache, able to store %zu elements\n", LogPrintf("Using %zu MiB out of %zu MiB requested for script execution cache, able to store %zu elements\n",
approx_size_bytes >> 20, max_size_bytes >> 20, num_elems); approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
return true; return true;