From ab14d1d6a4a8ef5fe5013150e6c5ebcb5f5e4ea9 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Mon, 20 May 2024 22:32:32 +0200 Subject: validation: Don't error if maxsigcachesize exceeds uint32::max Instead clamp it to uint32::max if it exceeds it. Co-authored-by: Anthony Towns --- src/cuckoocache.h | 14 ++++++-------- src/init.cpp | 7 ++----- src/script/sigcache.cpp | 8 ++------ src/script/sigcache.h | 1 - src/validation.cpp | 5 +---- 5 files changed, 11 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/cuckoocache.h b/src/cuckoocache.h index df320ed465..8370179395 100644 --- a/src/cuckoocache.h +++ b/src/cuckoocache.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -360,16 +359,15 @@ public: * structure * @returns A pair of the maximum number of elements storable (see setup() * 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> setup_bytes(size_t bytes) + std::pair setup_bytes(size_t bytes) { - size_t requested_num_elems = bytes / sizeof(Element); - if (std::numeric_limits::max() < requested_num_elems) { - return std::nullopt; - } + uint32_t requested_num_elems(std::min( + bytes / sizeof(Element), + std::numeric_limits::max())); - auto num_elems = setup(bytes/sizeof(Element)); + auto num_elems = setup(requested_num_elems); size_t approx_size_bytes = num_elems * sizeof(Element); return std::make_pair(num_elems, approx_size_bytes); diff --git a/src/init.cpp b/src/init.cpp index cb294ba84f..985b8d3d63 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1156,11 +1156,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ValidationCacheSizes validation_cache_sizes{}; ApplyArgsManOptions(args, validation_cache_sizes); - if (!InitSignatureCache(validation_cache_sizes.signature_cache_bytes) - || !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))); - } + (void)InitSignatureCache(validation_cache_sizes.signature_cache_bytes); + (void)InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes); assert(!node.scheduler); node.scheduler = std::make_unique(); diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 7c6c282cc4..666601d174 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -77,7 +76,7 @@ public: std::unique_lock lock(cs_sigcache); setValid.insert(entry); } - std::optional> setup_bytes(size_t n) + std::pair setup_bytes(size_t n) { return setValid.setup_bytes(n); } @@ -96,10 +95,7 @@ static CSignatureCache signatureCache; // signatureCache. bool InitSignatureCache(size_t max_size_bytes) { - auto setup_results = signatureCache.setup_bytes(max_size_bytes); - if (!setup_results) return false; - - const auto [num_elems, approx_size_bytes] = *setup_results; + const auto [num_elems, approx_size_bytes] = signatureCache.setup_bytes(max_size_bytes); 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); return true; diff --git a/src/script/sigcache.h b/src/script/sigcache.h index d33d60d5bc..26b8b9cd2a 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -10,7 +10,6 @@ #include #include -#include #include // DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit diff --git a/src/validation.cpp b/src/validation.cpp index 3e9ba08bb1..a9d26daf99 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2100,10 +2100,7 @@ bool InitScriptExecutionCache(size_t max_size_bytes) g_scriptExecutionCacheHasher.Write(nonce.begin(), 32); g_scriptExecutionCacheHasher.Write(nonce.begin(), 32); - auto setup_results = g_scriptExecutionCache.setup_bytes(max_size_bytes); - if (!setup_results) return false; - - const auto [num_elems, approx_size_bytes] = *setup_results; + const auto [num_elems, approx_size_bytes] = g_scriptExecutionCache.setup_bytes(max_size_bytes); 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); return true; -- cgit v1.2.3 From 13a3661aba95b54b822c99ecbb695b14a22536d2 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Fri, 17 May 2024 23:33:25 +0200 Subject: kernel: De-globalize script execution cache Move its ownership to the ChainstateManager class. Next to simplifying usage of the kernel library by no longer requiring manual setup of the cache prior to using validation code, it also slims down the amount of memory allocated by BasicTestingSetup. --- src/bitcoin-chainstate.cpp | 1 - src/init.cpp | 1 - src/kernel/chainstatemanager_opts.h | 2 ++ src/kernel/validation_cache_sizes.h | 1 - src/node/chainstatemanager_args.cpp | 9 +++++++++ src/node/validation_cache_args.cpp | 1 - src/script/sigcache.h | 1 + src/test/txvalidationcache_tests.cpp | 36 ++++++++++++++++++----------------- src/test/util/setup_common.cpp | 1 - src/validation.cpp | 37 +++++++++++++++++++++--------------- src/validation.h | 21 ++++++++++++++++---- 11 files changed, 70 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index ecbdcd48bb..d11d793d21 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -68,7 +68,6 @@ int main(int argc, char* argv[]) // performing the check with the signature cache. kernel::ValidationCacheSizes validation_cache_sizes{}; Assert(InitSignatureCache(validation_cache_sizes.signature_cache_bytes)); - Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes)); ValidationSignals validation_signals{std::make_unique()}; diff --git a/src/init.cpp b/src/init.cpp index 985b8d3d63..5accc63f37 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1157,7 +1157,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ValidationCacheSizes validation_cache_sizes{}; ApplyArgsManOptions(args, validation_cache_sizes); (void)InitSignatureCache(validation_cache_sizes.signature_cache_bytes); - (void)InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes); assert(!node.scheduler); node.scheduler = std::make_unique(); diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 076841c3c9..1b08eeeca7 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -9,6 +9,7 @@ #include #include +#include