Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ BITCOIN_CORE_H = \
instantsend/net_instantsend.h \
instantsend/signing.h \
kernel/coinstats.h \
kernel/validation_cache_sizes.h \
key.h \
key_io.h \
limitedmap.h \
Expand Down Expand Up @@ -314,6 +315,7 @@ BITCOIN_CORE_H = \
node/txreconciliation.h \
node/interface_ui.h \
node/utxo_snapshot.h \
node/validation_cache_args.h \
noui.h \
outputtype.h \
policy/feerate.h \
Expand Down Expand Up @@ -572,6 +574,7 @@ libbitcoin_node_a_SOURCES = \
node/transaction.cpp \
node/txreconciliation.cpp \
node/interface_ui.cpp \
node/validation_cache_args.cpp \
noui.cpp \
policy/fees.cpp \
policy/packages.cpp \
Expand Down
23 changes: 17 additions & 6 deletions src/cuckoocache.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
#include <atomic>
#include <cmath>
#include <cstring>
#include <limits>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

Expand Down Expand Up @@ -326,7 +328,7 @@ class cache
}

/** setup initializes the container to store no more than new_size
* elements.
* elements and no less than 2 elements.
*
* setup should only be called once.
*
Expand All @@ -336,8 +338,8 @@ class cache
uint32_t setup(uint32_t new_size)
{
// depth_limit must be at least one otherwise errors can occur.
depth_limit = static_cast<uint8_t>(std::log2(static_cast<float>(std::max((uint32_t)2, new_size))));
size = std::max<uint32_t>(2, new_size);
depth_limit = static_cast<uint8_t>(std::log2(static_cast<float>(size)));
table.resize(size);
collection_flags.setup(size);
epoch_flags.resize(size);
Expand All @@ -357,12 +359,21 @@ class cache
*
* @param bytes the approximate number of bytes to use for this data
* structure
* @returns the maximum number of elements storable (see setup()
* documentation for more detail)
* @returns A pair of the maximum number of elements storable (see setup()
* documentation for more detail) and the approxmiate total size of these
* elements in bytes or std::nullopt if the size requested is too large.
*/
uint32_t setup_bytes(size_t bytes)
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t bytes)
{
return setup(bytes/sizeof(Element));
size_t requested_num_elems = bytes / sizeof(Element);
if (std::numeric_limits<uint32_t>::max() < requested_num_elems) {
return std::nullopt;
}

auto num_elems = setup(bytes/sizeof(Element));

size_t approx_size_bytes = num_elems * sizeof(Element);
return std::make_pair(num_elems, approx_size_bytes);
Comment on lines +362 to +376
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

LGTM! The API change properly handles uint32_t overflow and returns useful sizing metadata.

Minor note: bytes/sizeof(Element) is computed twice (line 368 and 373). This is harmless since the compiler will likely optimize it, but could be simplified by reusing requested_num_elems after the overflow check:

-        auto num_elems = setup(bytes/sizeof(Element));
+        auto num_elems = setup(static_cast<uint32_t>(requested_num_elems));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* @returns A pair of the maximum number of elements storable (see setup()
* documentation for more detail) and the approxmiate total size of these
* elements in bytes or std::nullopt if the size requested is too large.
*/
uint32_t setup_bytes(size_t bytes)
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t bytes)
{
return setup(bytes/sizeof(Element));
size_t requested_num_elems = bytes / sizeof(Element);
if (std::numeric_limits<uint32_t>::max() < requested_num_elems) {
return std::nullopt;
}
auto num_elems = setup(bytes/sizeof(Element));
size_t approx_size_bytes = num_elems * sizeof(Element);
return std::make_pair(num_elems, approx_size_bytes);
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t bytes)
{
size_t requested_num_elems = bytes / sizeof(Element);
if (std::numeric_limits<uint32_t>::max() < requested_num_elems) {
return std::nullopt;
}
auto num_elems = setup(static_cast<uint32_t>(requested_num_elems));
size_t approx_size_bytes = num_elems * sizeof(Element);
return std::make_pair(num_elems, approx_size_bytes);
🤖 Prompt for AI Agents
In src/cuckoocache.h around lines 362 to 376, avoid recomputing
bytes/sizeof(Element) twice by reusing the already computed requested_num_elems:
after the overflow check call setup(requested_num_elems) (cast to the expected
type if necessary), compute approx_size_bytes as requested_num_elems *
sizeof(Element), and return the pair using that num and size.

}

/** insert loops at most depth_limit times trying to insert a hash
Expand Down
16 changes: 13 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <init.h>

#include <kernel/validation_cache_sizes.h>

#include <addrman.h>
#include <banman.h>
#include <base58.h>
Expand Down Expand Up @@ -45,6 +47,7 @@
#include <node/context.h>
#include <node/interface_ui.h>
#include <node/txreconciliation.h>
#include <node/validation_cache_args.h>
#include <policy/feerate.h>
#include <policy/fees.h>
#include <policy/policy.h>
Expand Down Expand Up @@ -138,7 +141,9 @@
#endif

using kernel::CoinStatsHashType;
using kernel::ValidationCacheSizes;

using node::ApplyArgsManOptions;
using node::CacheSizes;
using node::CalculateCacheSizes;
using node::ChainstateLoadingError;
Expand Down Expand Up @@ -763,7 +768,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-watchquorums=<n>", strprintf("Watch and validate quorum communication (default: %u)", llmq::DEFAULT_WATCH_QUORUMS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-capturemessages", "Capture all P2P messages to disk", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-disablegovernance", strprintf("Disable governance validation (0-1, default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_BYTES >> 20), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-minsporkkeys=<n>", "Overrides minimum spork signers to change spork value. Only useful for regtest and devnet. Using this on mainnet or testnet will ban you.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
Expand Down Expand Up @@ -1518,8 +1523,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
args.GetArg("-datadir", ""), fs::PathToString(fs::current_path()));
}

InitSignatureCache();
InitScriptExecutionCache();
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)));
}

int script_threads = args.GetIntArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
if (script_threads <= 0) {
Expand Down
20 changes: 20 additions & 0 deletions src/kernel/validation_cache_sizes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_KERNEL_VALIDATION_CACHE_SIZES_H
#define BITCOIN_KERNEL_VALIDATION_CACHE_SIZES_H

#include <script/sigcache.h>

#include <cstddef>
#include <limits>

namespace kernel {
struct ValidationCacheSizes {
size_t signature_cache_bytes{DEFAULT_MAX_SIG_CACHE_BYTES / 2};
size_t script_execution_cache_bytes{DEFAULT_MAX_SIG_CACHE_BYTES / 2};
};
}

#endif // BITCOIN_KERNEL_VALIDATION_CACHE_SIZES_H
36 changes: 36 additions & 0 deletions src/node/validation_cache_args.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <node/validation_cache_args.h>

#include <kernel/validation_cache_sizes.h>
#include <script/sigcache.h>

#include <util/system.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
Comment on lines +12 to +16
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Potentially unused includes.

The headers <memory> and <optional> don't appear to be used in this file. Consider removing them to keep includes minimal.

 #include <algorithm>
 #include <cstddef>
 #include <cstdint>
-#include <memory>
-#include <optional>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <algorithm>
#include <cstddef>
#include <cstdint>
🤖 Prompt for AI Agents
In src/node/validation_cache_args.cpp around lines 12 to 16, the includes
<memory> and <optional> appear unused; remove those two include lines to
minimize headers, then rebuild (and run unit tests or compile) to ensure nothing
breaks; if the compiler reports missing symbols, re-add only the specific needed
header(s) where those symbols are actually used.


using kernel::ValidationCacheSizes;

namespace node {
void ApplyArgsManOptions(const ArgsManager& argsman, ValidationCacheSizes& cache_sizes)
{
if (argsman.IsArgSet("-maxsigcachesize")) {
int64_t max_size = argsman.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_BYTES >> 20);
// 1. When supplied with a max_size of 0, both InitSignatureCache and
// InitScriptExecutionCache create the minimum possible cache (2
// elements). Therefore, we can use 0 as a floor here.
// 2. Multiply first, divide after to avoid integer truncation.
size_t clamped_size_each = std::max<int64_t>(max_size, 0) * (1 << 20) / 2;
cache_sizes = {
.signature_cache_bytes = clamped_size_each,
.script_execution_cache_bytes = clamped_size_each,
};
}
}
} // namespace node
17 changes: 17 additions & 0 deletions src/node/validation_cache_args.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
#define BITCOIN_NODE_VALIDATION_CACHE_ARGS_H

class ArgsManager;
namespace kernel {
struct ValidationCacheSizes;
};

namespace node {
void ApplyArgsManOptions(const ArgsManager& argsman, kernel::ValidationCacheSizes& cache_sizes);
} // namespace node

#endif // BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
Comment on lines +1 to +17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

LGTM!

New header file correctly declares the ApplyArgsManOptions function with proper forward declarations. The structure follows the upstream Bitcoin Core pattern for decoupling ArgsManager from kernel code.

Minor style note: Line 11 has a trailing semicolon after the namespace closing brace (};), which is unusual but valid C++.

 namespace kernel {
 struct ValidationCacheSizes;
-};
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
#define BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
class ArgsManager;
namespace kernel {
struct ValidationCacheSizes;
};
namespace node {
void ApplyArgsManOptions(const ArgsManager& argsman, kernel::ValidationCacheSizes& cache_sizes);
} // namespace node
#endif // BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
#define BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
class ArgsManager;
namespace kernel {
struct ValidationCacheSizes;
}
namespace node {
void ApplyArgsManOptions(const ArgsManager& argsman, kernel::ValidationCacheSizes& cache_sizes);
} // namespace node
#endif // BITCOIN_NODE_VALIDATION_CACHE_ARGS_H
🤖 Prompt for AI Agents
In src/node/validation_cache_args.h around lines 1 to 17, remove the stray
trailing semicolon after the closing brace of the kernel namespace (line 11) to
match typical style conventions; update the file by deleting that semicolon so
the namespace reads "namespace kernel { struct ValidationCacheSizes; }" without
an extra ';'.

18 changes: 10 additions & 8 deletions src/script/sigcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <cuckoocache.h>

#include <mutex>
#include <optional>
#include <shared_mutex>
#include <vector>

Expand Down Expand Up @@ -61,7 +62,7 @@ class CSignatureCache
std::unique_lock<std::shared_mutex> lock(cs_sigcache);
setValid.insert(entry);
}
uint32_t setup_bytes(size_t n)
std::optional<std::pair<uint32_t, size_t>> setup_bytes(size_t n)
{
return setValid.setup_bytes(n);
}
Expand All @@ -78,14 +79,15 @@ static CSignatureCache signatureCache;

// To be called once in AppInitMain/BasicTestingSetup to initialize the
// signatureCache.
void InitSignatureCache()
bool InitSignatureCache(size_t max_size_bytes)
{
// nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
// setup_bytes creates the minimum possible cache (2 elements).
size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
size_t nElems = signatureCache.setup_bytes(nMaxCacheSize);
LogPrintf("Using %zu MiB out of %zu/2 requested for signature cache, able to store %zu elements\n",
(nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);
auto setup_results = 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",
approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
return true;
}

bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
Expand Down
11 changes: 5 additions & 6 deletions src/script/sigcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
#include <script/interpreter.h>
#include <util/hasher.h>

#include <optional>
#include <vector>

// DoS prevention: limit cache size to 32MB (over 1000000 entries on 64-bit
// DoS prevention: limit cache size to 32MiB (over 1000000 entries on 64-bit
// systems). Due to how we count cache size, actual memory usage is slightly
// more (~32.25 MB)
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE = 32;
// Maximum sig cache size allowed
static const int64_t MAX_MAX_SIG_CACHE_SIZE = 16384;
// more (~32.25 MiB)
static constexpr size_t DEFAULT_MAX_SIG_CACHE_BYTES{32 << 20};

class CPubKey;

Expand All @@ -31,6 +30,6 @@ class CachingTransactionSignatureChecker : public TransactionSignatureChecker
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const override;
};

void InitSignatureCache();
[[nodiscard]] bool InitSignatureCache(size_t max_size_bytes);

#endif // BITCOIN_SCRIPT_SIGCACHE_H
10 changes: 7 additions & 3 deletions src/test/fuzz/script_sigcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>

#include <cstdint>
#include <optional>
#include <string>
#include <vector>

namespace {
const BasicTestingSetup* g_setup;
} // namespace

void initialize_script_sigcache()
{
ECC_Start();
SelectParams(CBaseChainParams::REGTEST);
InitSignatureCache();
static const auto testing_setup = MakeNoLogFileContext<>();
g_setup = testing_setup.get();
}

FUZZ_TARGET(script_sigcache, .init = initialize_script_sigcache)
Expand Down
5 changes: 0 additions & 5 deletions src/test/txvalidationcache_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,6 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup)
{
// Test that passing CheckInputScripts with one set of script flags doesn't imply
// that we would pass again with a different set of flags.
{
LOCK(cs_main);
InitScriptExecutionCache();
}

CScript p2pk_scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
CScript p2sh_scriptPubKey = GetScriptForDestination(ScriptHash(p2pk_scriptPubKey));
CScript p2pkh_scriptPubKey = GetScriptForDestination(PKHash(coinbaseKey.GetPubKey()));
Expand Down
12 changes: 10 additions & 2 deletions src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include <test/util/setup_common.h>

#include <kernel/validation_cache_sizes.h>

#include <addrman.h>
#include <banman.h>
#include <chainparams.h>
Expand All @@ -23,6 +25,7 @@
#include <node/blockstorage.h>
#include <node/chainstate.h>
#include <node/miner.h>
#include <node/validation_cache_args.h>
#include <policy/fees.h>
#include <pow.h>
#include <rpc/blockchain.h>
Expand Down Expand Up @@ -78,6 +81,8 @@
#include <memory>
#include <stdexcept>

using kernel::ValidationCacheSizes;
using node::ApplyArgsManOptions;
using node::BlockAssembler;
using node::CalculateCacheSizes;
using node::DashChainstateSetup;
Expand Down Expand Up @@ -187,8 +192,11 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
BLSInit();
SetupEnvironment();
SetupNetworking();
InitSignatureCache();
InitScriptExecutionCache();

ValidationCacheSizes validation_cache_sizes{};
ApplyArgsManOptions(*m_node.args, validation_cache_sizes);
Assert(InitSignatureCache(validation_cache_sizes.signature_cache_bytes));
Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes));

m_node.chain = interfaces::MakeChain(m_node);
m_node.netgroupman = std::make_unique<NetGroupManager>(/*asmap=*/std::vector<bool>());
Expand Down
17 changes: 10 additions & 7 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1828,20 +1828,23 @@ bool CScriptCheck::operator()() {
static CuckooCache::cache<uint256, SignatureCacheHasher> g_scriptExecutionCache;
static CSHA256 g_scriptExecutionCacheHasher;

void InitScriptExecutionCache() {
bool InitScriptExecutionCache(size_t max_size_bytes)
{
// Setup the salted hasher
uint256 nonce = GetRandHash();
// We want the nonce to be 64 bytes long to force the hasher to process
// this chunk, which makes later hash computations more efficient. We
// just write our 32-byte entropy twice to fill the 64 bytes.
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
g_scriptExecutionCacheHasher.Write(nonce.begin(), 32);
// nMaxCacheSize is unsigned. If -maxsigcachesize is set to zero,
// setup_bytes creates the minimum possible cache (2 elements).
size_t nMaxCacheSize = std::min(std::max((int64_t)0, gArgs.GetIntArg("-maxsigcachesize", DEFAULT_MAX_SIG_CACHE_SIZE) / 2), MAX_MAX_SIG_CACHE_SIZE) * ((size_t) 1 << 20);
size_t nElems = g_scriptExecutionCache.setup_bytes(nMaxCacheSize);
LogPrintf("Using %zu MiB out of %zu/2 requested for script execution cache, able to store %zu elements\n",
(nElems*sizeof(uint256)) >>20, (nMaxCacheSize*2)>>20, nElems);

auto setup_results = 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",
approx_size_bytes >> 20, max_size_bytes >> 20, num_elems);
return true;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ static_assert(std::is_nothrow_move_constructible_v<CScriptCheck>);
static_assert(std::is_nothrow_destructible_v<CScriptCheck>);

/** Initializes the script-execution cache */
void InitScriptExecutionCache();
[[nodiscard]] bool InitScriptExecutionCache(size_t max_size_bytes);

/** Functions for validating blocks and updating the block tree */

Expand Down