Compare commits

...

7 commits

Author SHA1 Message Date
Reproducibility Matters
ed4605711b
Merge 578654c686 into 433412fd84 2025-01-07 16:53:27 +01:00
TheCharlatan
578654c686
init: Use size_t consistently for cache sizes
This avoids having to rely on implicit casts when passing them to the
various functions allocating the caches.

This also fixes a bug where an incorrect amount of memory was allocated
on 32bit platforms. If the db cache size exceeded the maximum size of a
32 bit unsigned integer, it would overflow and allocate much less memory
than instructed to. Fix this by returning an error to the user if the
passed in dbcache size exceeeds the size of a size_t on that platform.

Add a release note for the change in behaviour on 32-bit systems.

Also take this opportunity to make the total amounts of cache in the
chainstate manager a size_t too.
2025-01-07 16:49:55 +01:00
TheCharlatan
1f81be60f5
kernel: Move kernel-related cache constants to kernel cache
They are not all related to the txdb, so a better place for them is the
new kernel cache file.
2025-01-07 16:49:54 +01:00
TheCharlatan
136e4080c2
kernel: Move non-kernel db cache size constants
These have nothing to do with the txdb, so move them out and into the
node caches.
2025-01-07 16:49:52 +01:00
TheCharlatan
41bc716488
kernel: Move kernel-specific cache size options to kernel
Carrying non-kernel related fields in the cache sizes for the indexes is
confusing for kernel library users. The cache sizes also are set
currently with magic numbers in bitcoin-chainstate. The comments for the
cache size calculations are also not completely clear.

Solve these things by moving the kernel-specific cache size fields to
their own struct.

This slightly changes the way the cache is allocated if the txindex
and/or blockfilterindex is used. Since they are now given precedence
over the block tree db cache, this results in a bit less cache being
allocated to the block tree db, coinsdb and coins caches. The effect is
negligible though, i.e. cache sizes with default dbcache reported
through the logs are:

master:
Cache configuration:
* Using 2.0 MiB for block index database
* Using 56.0 MiB for transaction index database
* Using 49.0 MiB for basic block filter index database
* Using 8.0 MiB for chain state database
* Using 335.0 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)

this branch:
Cache configuration:
* Using 2.0 MiB for block index database
* Using 56.2 MiB for transaction index database
* Using 49.2 MiB for basic block filter index database
* Using 8.0 MiB for chain state database
* Using 334.5 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)

Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
2025-01-07 16:49:47 +01:00
TheCharlatan
19316eccaf
init: Simplify coinsdb cache calculation
(total_cache / 4) + (1 << 23) is at least 8 MiB and nMaxCoinsDBCache is
also 8 MiB, so the minimum between the two will always be
nMaxCoinsDBCache.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
2025-01-03 18:15:26 +01:00
TheCharlatan
5db7d4d3d2
doc: Correct docstring describing max block tree db cache
It is always applied in the same way, no matter how the txindex is
setup. This was no longer accurate after 8181db8, where their
initialization was made independent.
2025-01-03 18:11:35 +01:00
14 changed files with 145 additions and 77 deletions

View file

@ -0,0 +1,6 @@
Updated settings
------
- On 32-bit systems an error is returned on startup if the user passes a
`-dbcache` value exceeding 4GiB.

View file

@ -19,9 +19,9 @@
#include <consensus/validation.h> #include <consensus/validation.h>
#include <core_io.h> #include <core_io.h>
#include <kernel/caches.h>
#include <logging.h> #include <logging.h>
#include <node/blockstorage.h> #include <node/blockstorage.h>
#include <node/caches.h>
#include <node/chainstate.h> #include <node/chainstate.h>
#include <random.h> #include <random.h>
#include <script/sigcache.h> #include <script/sigcache.h>
@ -123,10 +123,7 @@ int main(int argc, char* argv[])
util::SignalInterrupt interrupt; util::SignalInterrupt interrupt;
ChainstateManager chainman{interrupt, chainman_opts, blockman_opts}; ChainstateManager chainman{interrupt, chainman_opts, blockman_opts};
node::CacheSizes cache_sizes; kernel::CacheSizes cache_sizes{MiBToBytes(DEFAULT_KERNEL_CACHE)};
cache_sizes.block_tree_db = 2 << 20;
cache_sizes.coins_db = 2 << 22;
cache_sizes.coins = (450 << 20) - (2 << 20) - (2 << 22);
node::ChainstateLoadOptions options; node::ChainstateLoadOptions options;
auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options); auto [status, error] = node::LoadChainstate(chainman, cache_sizes, options);
if (status != node::ChainstateLoadStatus::SUCCESS) { if (status != node::ChainstateLoadStatus::SUCCESS) {

View file

@ -32,6 +32,7 @@
#include <interfaces/ipc.h> #include <interfaces/ipc.h>
#include <interfaces/mining.h> #include <interfaces/mining.h>
#include <interfaces/node.h> #include <interfaces/node.h>
#include <kernel/caches.h>
#include <kernel/context.h> #include <kernel/context.h>
#include <key.h> #include <key.h>
#include <logging.h> #include <logging.h>
@ -119,9 +120,10 @@ using common::AmountErrMsg;
using common::InvalidPortErrMsg; using common::InvalidPortErrMsg;
using common::ResolveErrMsg; using common::ResolveErrMsg;
using kernel::CacheSizes;
using node::ApplyArgsManOptions; using node::ApplyArgsManOptions;
using node::BlockManager; using node::BlockManager;
using node::CacheSizes;
using node::CalculateCacheSizes; using node::CalculateCacheSizes;
using node::ChainstateLoadResult; using node::ChainstateLoadResult;
using node::ChainstateLoadStatus; using node::ChainstateLoadStatus;
@ -487,7 +489,7 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
argsman.AddArg("-conf=<file>", strprintf("Specify path to read-only configuration file. Relative paths will be prefixed by datadir location (only useable from command line, not configuration file) (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-conf=<file>", strprintf("Specify path to read-only configuration file. Relative paths will be prefixed by datadir location (only useable from command line, not configuration file) (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS); argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
argsman.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS); argsman.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
argsman.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (minimum %d, default: %d). Make sure you have enough RAM. In addition, unused memory allocated to the mempool is shared with this cache (see -maxmempool).", nMinDbCache, nDefaultDbCache), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (minimum %d, default: %d). Make sure you have enough RAM. In addition, unused memory allocated to the mempool is shared with this cache (see -maxmempool).", MIN_DB_CACHE, DEFAULT_DB_CACHE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-allowignoredconf", strprintf("For backwards compatibility, treat an unused %s file in the datadir as a warning, not an error.", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-allowignoredconf", strprintf("For backwards compatibility, treat an unused %s file in the datadir as a warning, not an error.", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-loadblock=<file>", "Imports blocks from external file on startup", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-loadblock=<file>", "Imports blocks from external file on startup", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
@ -1603,18 +1605,22 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
ReadNotificationArgs(args, kernel_notifications); ReadNotificationArgs(args, kernel_notifications);
// cache size calculations // cache size calculations
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size()); const auto cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());
if (!cache_sizes) {
return InitError(_("Failed to calculate cache sizes. Try lowering the -dbcache value."));
}
auto [index_cache_sizes, kernel_cache_sizes] = *cache_sizes;
LogPrintf("Cache configuration:\n"); LogInfo("Cache configuration:");
LogPrintf("* Using %.1f MiB for block index database\n", cache_sizes.block_tree_db * (1.0 / 1024 / 1024)); LogInfo("* Using %.1f MiB for block index database", kernel_cache_sizes.block_tree_db * (1.0 / 1024 / 1024));
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
LogPrintf("* Using %.1f MiB for transaction index database\n", cache_sizes.tx_index * (1.0 / 1024 / 1024)); LogInfo("* Using %.1f MiB for transaction index database", index_cache_sizes.tx_index * (1.0 / 1024 / 1024));
} }
for (BlockFilterType filter_type : g_enabled_filter_types) { for (BlockFilterType filter_type : g_enabled_filter_types) {
LogPrintf("* Using %.1f MiB for %s block filter index database\n", LogInfo("* Using %.1f MiB for %s block filter index database",
cache_sizes.filter_index * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type)); index_cache_sizes.filter_index * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type));
} }
LogPrintf("* Using %.1f MiB for chain state database\n", cache_sizes.coins_db * (1.0 / 1024 / 1024)); LogInfo("* Using %.1f MiB for chain state database", kernel_cache_sizes.coins_db * (1.0 / 1024 / 1024));
assert(!node.mempool); assert(!node.mempool);
assert(!node.chainman); assert(!node.chainman);
@ -1627,7 +1633,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node, node,
do_reindex, do_reindex,
do_reindex_chainstate, do_reindex_chainstate,
cache_sizes, kernel_cache_sizes,
args); args);
if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) { if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) {
// suggest a reindex // suggest a reindex
@ -1646,7 +1652,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node, node,
do_reindex, do_reindex,
do_reindex_chainstate, do_reindex_chainstate,
cache_sizes, kernel_cache_sizes,
args); args);
} }
if (status != ChainstateLoadStatus::SUCCESS && status != ChainstateLoadStatus::INTERRUPTED) { if (status != ChainstateLoadStatus::SUCCESS && status != ChainstateLoadStatus::INTERRUPTED) {
@ -1672,12 +1678,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers // ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, do_reindex); g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), index_cache_sizes.tx_index, false, do_reindex);
node.indexes.emplace_back(g_txindex.get()); node.indexes.emplace_back(g_txindex.get());
} }
for (const auto& filter_type : g_enabled_filter_types) { for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, do_reindex); InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, index_cache_sizes.filter_index, false, do_reindex);
node.indexes.emplace_back(GetBlockFilterIndex(filter_type)); node.indexes.emplace_back(GetBlockFilterIndex(filter_type));
} }

48
src/kernel/caches.h Normal file
View file

@ -0,0 +1,48 @@
// Copyright (c) 2024-present 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_CACHES_H
#define BITCOIN_KERNEL_CACHES_H
#include <util/check.h>
#include <algorithm>
#include <bit>
#include <cstdint>
#include <limits>
//! Suggested default amount of cache reserved for the kernel (MiB)
static constexpr int64_t DEFAULT_KERNEL_CACHE{450};
//! Max memory allocated to block tree DB specific cache (MiB)
static constexpr int64_t MAX_BLOCK_DB_CACHE{2};
//! Max memory allocated to coin DB specific cache (MiB)
static constexpr int64_t MAX_COINS_DB_CACHE{8};
//! Guard against truncation of values before converting.
constexpr size_t MiBToBytes(int64_t mib)
{
Assert(std::countl_zero(static_cast<uint64_t>(mib)) >= 21); // Ensure sign bit is unset + enough zeros to shift.
const int64_t bytes{mib << 20};
Assert(static_cast<uint64_t>(bytes) <= std::numeric_limits<size_t>::max());
return static_cast<size_t>(bytes);
}
namespace kernel {
struct CacheSizes {
size_t block_tree_db;
size_t coins_db;
size_t coins;
CacheSizes(size_t total_cache)
{
block_tree_db = std::min(total_cache / 8, MiBToBytes(MAX_BLOCK_DB_CACHE));
total_cache -= block_tree_db;
coins_db = std::min(total_cache / 2, MiBToBytes(MAX_COINS_DB_CACHE));
total_cache -= coins_db;
coins = total_cache; // the rest goes to the coins cache
}
};
} // namespace kernel
#endif // BITCOIN_KERNEL_CACHES_H

View file

@ -6,28 +6,42 @@
#include <common/args.h> #include <common/args.h>
#include <index/txindex.h> #include <index/txindex.h>
#include <txdb.h> #include <kernel/caches.h>
#include <logging.h>
#include <algorithm>
#include <optional>
#include <string>
// Unlike for the UTXO database, for the txindex scenario the leveldb cache make
// a meaningful difference: https://github.com/bitcoin/bitcoin/pull/8273#issuecomment-229601991
//! Max memory allocated to tx index DB specific cache in MiB.
static constexpr int64_t MAX_TX_INDEX_CACHE{1024};
//! Max memory allocated to all block filter index caches combined in MiB.
static constexpr int64_t MAX_FILTER_INDEX_CACHE{1024};
namespace node { namespace node {
CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) std::optional<CacheSizes> CalculateCacheSizes(const ArgsManager& args, size_t n_indexes)
{ {
int64_t nTotalCache = (args.GetIntArg("-dbcache", nDefaultDbCache) << 20); int64_t db_cache = args.GetIntArg("-dbcache", DEFAULT_DB_CACHE);
nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache if (static_cast<uint64_t>(db_cache << 20) > std::numeric_limits<size_t>::max()) {
CacheSizes sizes; LogWarning("Cannot allocate more than %d MiB in total for db caches.", static_cast<double>(std::numeric_limits<size_t>::max()) * (1.0 / 1024 / 1024));
sizes.block_tree_db = std::min(nTotalCache / 8, nMaxBlockDBCache << 20); return std::nullopt;
nTotalCache -= sizes.block_tree_db;
sizes.tx_index = std::min(nTotalCache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0);
nTotalCache -= sizes.tx_index;
sizes.filter_index = 0;
if (n_indexes > 0) {
int64_t max_cache = std::min(nTotalCache / 8, max_filter_index_cache << 20);
sizes.filter_index = max_cache / n_indexes;
nTotalCache -= sizes.filter_index * n_indexes;
} }
sizes.coins_db = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
sizes.coins_db = std::min(sizes.coins_db, nMaxCoinsDBCache << 20); // cap total coins db cache // negative values are permitted, but interpreted as zero.
nTotalCache -= sizes.coins_db; db_cache = std::max(int64_t{0}, db_cache);
sizes.coins = nTotalCache; // the rest goes to in-memory cache size_t total_cache = std::max(MiBToBytes(db_cache), MiBToBytes(MIN_DB_CACHE));
return sizes;
IndexCacheSizes index_sizes;
index_sizes.tx_index = std::min(total_cache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? MiBToBytes(MAX_TX_INDEX_CACHE) : 0);
total_cache -= index_sizes.tx_index;
index_sizes.filter_index = 0;
if (n_indexes > 0) {
int64_t max_cache = std::min(total_cache / 8, MiBToBytes(MAX_FILTER_INDEX_CACHE));
index_sizes.filter_index = max_cache / n_indexes;
total_cache -= index_sizes.filter_index * n_indexes;
}
return {{index_sizes, kernel::CacheSizes{total_cache}}};
} }
} // namespace node } // namespace node

View file

@ -5,20 +5,29 @@
#ifndef BITCOIN_NODE_CACHES_H #ifndef BITCOIN_NODE_CACHES_H
#define BITCOIN_NODE_CACHES_H #define BITCOIN_NODE_CACHES_H
#include <kernel/caches.h>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <optional>
class ArgsManager; class ArgsManager;
//! min. -dbcache (MiB)
static constexpr int64_t MIN_DB_CACHE{4};
//! -dbcache default (MiB)
static constexpr int64_t DEFAULT_DB_CACHE{DEFAULT_KERNEL_CACHE};
namespace node { namespace node {
struct CacheSizes { struct IndexCacheSizes {
int64_t block_tree_db; size_t tx_index;
int64_t coins_db; size_t filter_index;
int64_t coins;
int64_t tx_index;
int64_t filter_index;
}; };
CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes = 0); struct CacheSizes {
IndexCacheSizes index;
kernel::CacheSizes kernel;
};
std::optional<CacheSizes> CalculateCacheSizes(const ArgsManager& args, size_t n_indexes = 0);
} // namespace node } // namespace node
#endif // BITCOIN_NODE_CACHES_H #endif // BITCOIN_NODE_CACHES_H

View file

@ -8,9 +8,9 @@
#include <chain.h> #include <chain.h>
#include <coins.h> #include <coins.h>
#include <consensus/params.h> #include <consensus/params.h>
#include <kernel/caches.h>
#include <logging.h> #include <logging.h>
#include <node/blockstorage.h> #include <node/blockstorage.h>
#include <node/caches.h>
#include <sync.h> #include <sync.h>
#include <threadsafety.h> #include <threadsafety.h>
#include <tinyformat.h> #include <tinyformat.h>
@ -29,6 +29,8 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
using kernel::CacheSizes;
namespace node { namespace node {
// Complete initialization of chainstates after the initial call has been made // Complete initialization of chainstates after the initial call has been made
// to ChainstateManager::InitializeChainstate(). // to ChainstateManager::InitializeChainstate().
@ -44,7 +46,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
try { try {
pblocktree = std::make_unique<BlockTreeDB>(DBParams{ pblocktree = std::make_unique<BlockTreeDB>(DBParams{
.path = chainman.m_options.datadir / "blocks" / "index", .path = chainman.m_options.datadir / "blocks" / "index",
.cache_bytes = static_cast<size_t>(cache_sizes.block_tree_db), .cache_bytes = cache_sizes.block_tree_db,
.memory_only = options.block_tree_db_in_memory, .memory_only = options.block_tree_db_in_memory,
.wipe_data = options.wipe_block_tree_db, .wipe_data = options.wipe_block_tree_db,
.options = chainman.m_options.block_tree_db}); .options = chainman.m_options.block_tree_db});

View file

@ -14,9 +14,11 @@
class CTxMemPool; class CTxMemPool;
namespace node { namespace kernel {
struct CacheSizes; struct CacheSizes;
} // namespace kernel
namespace node {
struct ChainstateLoadOptions { struct ChainstateLoadOptions {
CTxMemPool* mempool{nullptr}; CTxMemPool* mempool{nullptr};
@ -69,7 +71,7 @@ using ChainstateLoadResult = std::tuple<ChainstateLoadStatus, bilingual_str>;
* *
* LoadChainstate returns a (status code, error string) tuple. * LoadChainstate returns a (status code, error string) tuple.
*/ */
ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSizes& cache_sizes, ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const kernel::CacheSizes& cache_sizes,
const ChainstateLoadOptions& options); const ChainstateLoadOptions& options);
ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const ChainstateLoadOptions& options); ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const ChainstateLoadOptions& options);
} // namespace node } // namespace node

View file

@ -15,9 +15,9 @@
#include <common/system.h> #include <common/system.h>
#include <interfaces/node.h> #include <interfaces/node.h>
#include <node/chainstatemanager_args.h>
#include <netbase.h> #include <netbase.h>
#include <txdb.h> #include <node/caches.h>
#include <node/chainstatemanager_args.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <chrono> #include <chrono>
@ -95,7 +95,7 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
ui->verticalLayout->setStretchFactor(ui->tabWidget, 1); ui->verticalLayout->setStretchFactor(ui->tabWidget, 1);
/* Main elements init */ /* Main elements init */
ui->databaseCache->setRange(nMinDbCache, std::numeric_limits<int>::max()); ui->databaseCache->setRange(MIN_DB_CACHE, std::numeric_limits<int>::max());
ui->threadsScriptVerif->setMinimum(-GetNumCores()); ui->threadsScriptVerif->setMinimum(-GetNumCores());
ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS); ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
ui->pruneWarning->setVisible(false); ui->pruneWarning->setVisible(false);

View file

@ -15,8 +15,8 @@
#include <mapport.h> #include <mapport.h>
#include <net.h> #include <net.h>
#include <netbase.h> #include <netbase.h>
#include <node/caches.h>
#include <node/chainstatemanager_args.h> #include <node/chainstatemanager_args.h>
#include <txdb.h> // for -dbcache defaults
#include <util/string.h> #include <util/string.h>
#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS #include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
#include <wallet/wallet.h> // For DEFAULT_SPEND_ZEROCONF_CHANGE #include <wallet/wallet.h> // For DEFAULT_SPEND_ZEROCONF_CHANGE
@ -470,7 +470,7 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con
suffix.empty() ? getOption(option, "-prev") : suffix.empty() ? getOption(option, "-prev") :
DEFAULT_PRUNE_TARGET_GB; DEFAULT_PRUNE_TARGET_GB;
case DatabaseCache: case DatabaseCache:
return qlonglong(SettingToInt(setting(), nDefaultDbCache)); return qlonglong(SettingToInt(setting(), DEFAULT_DB_CACHE));
case ThreadsScriptVerif: case ThreadsScriptVerif:
return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS)); return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS));
case Listen: case Listen:
@ -733,7 +733,7 @@ void OptionsModel::checkAndMigrate()
// see https://github.com/bitcoin/bitcoin/pull/8273 // see https://github.com/bitcoin/bitcoin/pull/8273
// force people to upgrade to the new value if they are using 100MB // force people to upgrade to the new value if they are using 100MB
if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100) if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100)
settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); settings.setValue("nDatabaseCache", (qint64)DEFAULT_DB_CACHE);
settings.setValue(strSettingsVersionKey, CLIENT_VERSION); settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
} }

View file

@ -66,7 +66,6 @@ using kernel::BlockTreeDB;
using node::ApplyArgsManOptions; using node::ApplyArgsManOptions;
using node::BlockAssembler; using node::BlockAssembler;
using node::BlockManager; using node::BlockManager;
using node::CalculateCacheSizes;
using node::KernelNotifications; using node::KernelNotifications;
using node::LoadChainstate; using node::LoadChainstate;
using node::RegenerateCommitments; using node::RegenerateCommitments;
@ -229,8 +228,6 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
Assert(error.empty()); Assert(error.empty());
m_node.warnings = std::make_unique<node::Warnings>(); m_node.warnings = std::make_unique<node::Warnings>();
m_cache_sizes = CalculateCacheSizes(m_args);
m_node.notifications = std::make_unique<KernelNotifications>(Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings)); m_node.notifications = std::make_unique<KernelNotifications>(Assert(m_node.shutdown_request), m_node.exit_status, *Assert(m_node.warnings));
m_make_chainman = [this, &chainparams, opts] { m_make_chainman = [this, &chainparams, opts] {
@ -256,7 +253,7 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, TestOpts opts)
LOCK(m_node.chainman->GetMutex()); LOCK(m_node.chainman->GetMutex());
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<BlockTreeDB>(DBParams{ m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<BlockTreeDB>(DBParams{
.path = m_args.GetDataDirNet() / "blocks" / "index", .path = m_args.GetDataDirNet() / "blocks" / "index",
.cache_bytes = static_cast<size_t>(m_cache_sizes.block_tree_db), .cache_bytes = m_kernel_cache_sizes.block_tree_db,
.memory_only = true, .memory_only = true,
}); });
}; };
@ -292,7 +289,7 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL); options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
options.require_full_verification = m_args.IsArgSet("-checkblocks") || m_args.IsArgSet("-checklevel"); options.require_full_verification = m_args.IsArgSet("-checkblocks") || m_args.IsArgSet("-checklevel");
auto [status, error] = LoadChainstate(chainman, m_cache_sizes, options); auto [status, error] = LoadChainstate(chainman, m_kernel_cache_sizes, options);
assert(status == node::ChainstateLoadStatus::SUCCESS); assert(status == node::ChainstateLoadStatus::SUCCESS);
std::tie(status, error) = VerifyLoadedChainstate(chainman, options); std::tie(status, error) = VerifyLoadedChainstate(chainman, options);

View file

@ -6,6 +6,7 @@
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H #define BITCOIN_TEST_UTIL_SETUP_COMMON_H
#include <common/args.h> // IWYU pragma: export #include <common/args.h> // IWYU pragma: export
#include <kernel/caches.h>
#include <kernel/context.h> #include <kernel/context.h>
#include <key.h> #include <key.h>
#include <node/caches.h> #include <node/caches.h>
@ -103,7 +104,7 @@ struct BasicTestingSetup {
* initialization behaviour. * initialization behaviour.
*/ */
struct ChainTestingSetup : public BasicTestingSetup { struct ChainTestingSetup : public BasicTestingSetup {
node::CacheSizes m_cache_sizes{}; kernel::CacheSizes m_kernel_cache_sizes{node::CalculateCacheSizes(m_args).value().kernel};
bool m_coins_db_in_memory{true}; bool m_coins_db_in_memory{true};
bool m_block_tree_db_in_memory{true}; bool m_block_tree_db_in_memory{true};
std::function<void()> m_make_chainman{}; std::function<void()> m_make_chainman{};

View file

@ -21,22 +21,8 @@
class COutPoint; class COutPoint;
class uint256; class uint256;
//! -dbcache default (MiB)
static const int64_t nDefaultDbCache = 450;
//! -dbbatchsize default (bytes) //! -dbbatchsize default (bytes)
static const int64_t nDefaultDbBatchSize = 16 << 20; static const int64_t nDefaultDbBatchSize = 16 << 20;
//! min. -dbcache (MiB)
static const int64_t nMinDbCache = 4;
//! Max memory allocated to block tree DB specific cache, if no -txindex (MiB)
static const int64_t nMaxBlockDBCache = 2;
//! Max memory allocated to block tree DB specific cache, if -txindex (MiB)
// Unlike for the UTXO database, for the txindex scenario the leveldb cache make
// a meaningful difference: https://github.com/bitcoin/bitcoin/pull/8273#issuecomment-229601991
static const int64_t nMaxTxIndexCache = 1024;
//! Max memory allocated to all block filter index caches combined in MiB.
static const int64_t max_filter_index_cache = 1024;
//! Max memory allocated to coin DB specific cache (MiB)
static const int64_t nMaxCoinsDBCache = 8;
//! User-controlled performance and debug options. //! User-controlled performance and debug options.
struct CoinsViewOptions { struct CoinsViewOptions {

View file

@ -1064,11 +1064,11 @@ public:
//! The total number of bytes available for us to use across all in-memory //! The total number of bytes available for us to use across all in-memory
//! coins caches. This will be split somehow across chainstates. //! coins caches. This will be split somehow across chainstates.
int64_t m_total_coinstip_cache{0}; size_t m_total_coinstip_cache{0};
// //
//! The total number of bytes available for us to use across all leveldb //! The total number of bytes available for us to use across all leveldb
//! coins databases. This will be split somehow across chainstates. //! coins databases. This will be split somehow across chainstates.
int64_t m_total_coinsdb_cache{0}; size_t m_total_coinsdb_cache{0};
//! Instantiate a new chainstate. //! Instantiate a new chainstate.
//! //!