From 2c43b6adebbfabb3c8dd82fe821ce0a5d6173b3b Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Thu, 15 May 2025 17:45:44 -0400 Subject: [PATCH 1/2] init: cap -maxmempool to 500 MB on 32-bit systems 32-bit architecture is limited to 4GiB, so it doesn't make sense to set a too high value. 500 MB is chosen as an arbitrary maximum value that seems reasonable. --- src/node/mempool_args.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index 6dbba783815..58ec730b965 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -25,6 +25,9 @@ using common::AmountErrMsg; using kernel::MemPoolLimits; using kernel::MemPoolOptions; +//! Maximum mempool size on 32-bit systems. +static constexpr int MAX_32BIT_MEMPOOL_MB{500}; + namespace { void ApplyArgsManOptions(const ArgsManager& argsman, MemPoolLimits& mempool_limits) { @@ -42,7 +45,13 @@ util::Result ApplyArgsManOptions(const ArgsManager& argsman, const CChainP { mempool_opts.check_ratio = argsman.GetIntArg("-checkmempool", mempool_opts.check_ratio); - if (auto mb = argsman.GetIntArg("-maxmempool")) mempool_opts.max_size_bytes = *mb * 1'000'000; + if (auto mb = argsman.GetIntArg("-maxmempool")) { + constexpr bool is_32bit{sizeof(void*) == 4}; + if (is_32bit && *mb > MAX_32BIT_MEMPOOL_MB) { + return util::Error{Untranslated(strprintf("-maxmempool is set to %i but can't be over %i MB on 32-bit systems", *mb, MAX_32BIT_MEMPOOL_MB))}; + } + mempool_opts.max_size_bytes = *mb * 1'000'000; + } if (auto hours = argsman.GetIntArg("-mempoolexpiry")) mempool_opts.expiry = std::chrono::hours{*hours}; From 9f8e7b0b3b787b873045a4a8194e77d0b0a2b3b6 Mon Sep 17 00:00:00 2001 From: Antoine Poinsot Date: Fri, 16 May 2025 09:12:25 -0400 Subject: [PATCH 2/2] node: cap -dbcache to 1GiB on 32-bit architectures 32-bit architecture is limited to 4GiB, so it doesn't make sense to set a too high value. Since this setting is performance critical, pick an arbitrary value higher than for -maxmempool but still reasonable. --- src/node/caches.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/node/caches.cpp b/src/node/caches.cpp index 8b432637c73..d5d69fc2044 100644 --- a/src/node/caches.cpp +++ b/src/node/caches.cpp @@ -19,6 +19,8 @@ static constexpr size_t MAX_TX_INDEX_CACHE{1024_MiB}; //! Max memory allocated to all block filter index caches combined in bytes. static constexpr size_t MAX_FILTER_INDEX_CACHE{1024_MiB}; +//! Maximum dbcache size on 32-bit systems. +static constexpr size_t MAX_32BIT_DBCACHE{1024_MiB}; namespace node { CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) @@ -28,7 +30,8 @@ CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) if (std::optional db_cache = args.GetIntArg("-dbcache")) { if (*db_cache < 0) db_cache = 0; uint64_t db_cache_bytes = SaturatingLeftShift(*db_cache, 20); - total_cache = std::max(MIN_DB_CACHE, std::min(db_cache_bytes, std::numeric_limits::max())); + constexpr auto max_db_cache{sizeof(void*) == 4 ? MAX_32BIT_DBCACHE : std::numeric_limits::max()}; + total_cache = std::max(MIN_DB_CACHE, std::min(db_cache_bytes, max_db_cache)); } IndexCacheSizes index_sizes;