aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/node/coins_view_args.cpp16
-rw-r--r--src/node/coins_view_args.h15
-rw-r--r--src/test/coins_tests.cpp4
-rw-r--r--src/txdb.cpp34
-rw-r--r--src/txdb.h18
-rw-r--r--src/validation.cpp21
-rw-r--r--src/validation.h2
8 files changed, 72 insertions, 40 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d5f2eebd3..7b9ffe427d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -204,6 +204,7 @@ BITCOIN_CORE_H = \
node/chainstate.h \
node/chainstatemanager_args.h \
node/coin.h \
+ node/coins_view_args.h \
node/connection_types.h \
node/context.h \
node/database_args.h \
@@ -389,6 +390,7 @@ libbitcoin_node_a_SOURCES = \
node/chainstate.cpp \
node/chainstatemanager_args.cpp \
node/coin.cpp \
+ node/coins_view_args.cpp \
node/connection_types.cpp \
node/context.cpp \
node/database_args.cpp \
diff --git a/src/node/coins_view_args.cpp b/src/node/coins_view_args.cpp
new file mode 100644
index 0000000000..67c9b8dbac
--- /dev/null
+++ b/src/node/coins_view_args.cpp
@@ -0,0 +1,16 @@
+// 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/coins_view_args.h>
+
+#include <txdb.h>
+#include <util/system.h>
+
+namespace node {
+void ReadCoinsViewArgs(const ArgsManager& args, CoinsViewOptions& options)
+{
+ if (auto value = args.GetIntArg("-dbbatchsize")) options.batch_write_bytes = *value;
+ if (auto value = args.GetIntArg("-dbcrashratio")) options.simulate_crash_ratio = *value;
+}
+} // namespace node
diff --git a/src/node/coins_view_args.h b/src/node/coins_view_args.h
new file mode 100644
index 0000000000..71a7a671fd
--- /dev/null
+++ b/src/node/coins_view_args.h
@@ -0,0 +1,15 @@
+// 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_COINS_VIEW_ARGS_H
+#define BITCOIN_NODE_COINS_VIEW_ARGS_H
+
+class ArgsManager;
+struct CoinsViewOptions;
+
+namespace node {
+void ReadCoinsViewArgs(const ArgsManager& args, CoinsViewOptions& options);
+} // namespace node
+
+#endif // BITCOIN_NODE_COINS_VIEW_ARGS_H
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 55ecd41af1..eb33e0028e 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test)
CCoinsViewTest base;
SimulationTest(&base, false);
- CCoinsViewDB db_base{"test", /*nCacheSize=*/1 << 23, /*fMemory=*/true, /*fWipe=*/false};
+ CCoinsViewDB db_base{{.path = "test", .cache_bytes = 1 << 23, .memory_only = true}, {}};
SimulationTest(&db_base, true);
}
@@ -1064,7 +1064,7 @@ void TestFlushBehavior(
BOOST_AUTO_TEST_CASE(ccoins_flush_behavior)
{
// Create two in-memory caches atop a leveldb view.
- CCoinsViewDB base{"test", /*nCacheSize=*/ 1 << 23, /*fMemory=*/ true, /*fWipe=*/ false};
+ CCoinsViewDB base{{.path = "test", .cache_bytes = 1 << 23, .memory_only = true}, {}};
std::vector<std::unique_ptr<CCoinsViewCacheTest>> caches;
caches.push_back(std::make_unique<CCoinsViewCacheTest>(&base));
caches.push_back(std::make_unique<CCoinsViewCacheTest>(caches.back().get()));
diff --git a/src/txdb.cpp b/src/txdb.cpp
index 697eaa926d..5803bc7b31 100644
--- a/src/txdb.cpp
+++ b/src/txdb.cpp
@@ -71,32 +71,22 @@ struct CoinEntry {
} // namespace
-CCoinsViewDB::CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe) :
- m_db{std::make_unique<CDBWrapper>(DBParams{
- .path = ldb_path,
- .cache_bytes = nCacheSize,
- .memory_only = fMemory,
- .wipe_data = fWipe,
- .obfuscate = true,
- .options = [] { DBOptions options; node::ReadDatabaseArgs(gArgs, options); return options; }()})},
- m_ldb_path(ldb_path),
- m_is_memory(fMemory) { }
+CCoinsViewDB::CCoinsViewDB(DBParams db_params, CoinsViewOptions options) :
+ m_db_params{std::move(db_params)},
+ m_options{std::move(options)},
+ m_db{std::make_unique<CDBWrapper>(m_db_params)} { }
void CCoinsViewDB::ResizeCache(size_t new_cache_size)
{
// We can't do this operation with an in-memory DB since we'll lose all the coins upon
// reset.
- if (!m_is_memory) {
+ if (!m_db_params.memory_only) {
// Have to do a reset first to get the original `m_db` state to release its
// filesystem lock.
m_db.reset();
- m_db = std::make_unique<CDBWrapper>(DBParams{
- .path = m_ldb_path,
- .cache_bytes = new_cache_size,
- .memory_only = m_is_memory,
- .wipe_data = false,
- .obfuscate = true,
- .options = [] { DBOptions options; node::ReadDatabaseArgs(gArgs, options); return options; }()});
+ m_db_params.cache_bytes = new_cache_size;
+ m_db_params.wipe_data = false;
+ m_db = std::make_unique<CDBWrapper>(m_db_params);
}
}
@@ -127,8 +117,6 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, boo
CDBBatch batch(*m_db);
size_t count = 0;
size_t changed = 0;
- size_t batch_size = (size_t)gArgs.GetIntArg("-dbbatchsize", nDefaultDbBatchSize);
- int crash_simulate = gArgs.GetIntArg("-dbcrashratio", 0);
assert(!hashBlock.IsNull());
uint256 old_tip = GetBestBlock();
@@ -159,13 +147,13 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, boo
}
count++;
it = erase ? mapCoins.erase(it) : std::next(it);
- if (batch.SizeEstimate() > batch_size) {
+ if (batch.SizeEstimate() > m_options.batch_write_bytes) {
LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
m_db->WriteBatch(batch);
batch.Clear();
- if (crash_simulate) {
+ if (m_options.simulate_crash_ratio) {
static FastRandomContext rng;
- if (rng.randrange(crash_simulate) == 0) {
+ if (rng.randrange(m_options.simulate_crash_ratio) == 0) {
LogPrintf("Simulating a crash. Goodbye.\n");
_Exit(0);
}
diff --git a/src/txdb.h b/src/txdb.h
index e3422846c0..bfbfab57a4 100644
--- a/src/txdb.h
+++ b/src/txdb.h
@@ -45,18 +45,24 @@ 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.
+struct CoinsViewOptions {
+ //! Maximum database write batch size in bytes.
+ size_t batch_write_bytes = nDefaultDbBatchSize;
+ //! If non-zero, randomly exit when the database is flushed with (1/ratio)
+ //! probability.
+ int simulate_crash_ratio = 0;
+};
+
/** CCoinsView backed by the coin database (chainstate/) */
class CCoinsViewDB final : public CCoinsView
{
protected:
+ DBParams m_db_params;
+ CoinsViewOptions m_options;
std::unique_ptr<CDBWrapper> m_db;
- fs::path m_ldb_path;
- bool m_is_memory;
public:
- /**
- * @param[in] ldb_path Location in the filesystem where leveldb data will be stored.
- */
- explicit CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe);
+ explicit CCoinsViewDB(DBParams db_params, CoinsViewOptions options);
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override;
bool HaveCoin(const COutPoint &outpoint) const override;
diff --git a/src/validation.cpp b/src/validation.cpp
index f0ffb748dd..971eb346a4 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -28,6 +28,8 @@
#include <node/blockstorage.h>
#include <node/interface_ui.h>
#include <node/utxo_snapshot.h>
+#include <node/coins_view_args.h>
+#include <node/database_args.h>
#include <policy/policy.h>
#include <policy/rbf.h>
#include <policy/settings.h>
@@ -1511,13 +1513,9 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
return nSubsidy;
}
-CoinsViews::CoinsViews(
- fs::path ldb_name,
- size_t cache_size_bytes,
- bool in_memory,
- bool should_wipe) : m_dbview(
- gArgs.GetDataDirNet() / ldb_name, cache_size_bytes, in_memory, should_wipe),
- m_catcherview(&m_dbview) {}
+CoinsViews::CoinsViews(DBParams db_params, CoinsViewOptions options)
+ : m_dbview{std::move(db_params), std::move(options)},
+ m_catcherview(&m_dbview) {}
void CoinsViews::InitCache()
{
@@ -1546,7 +1544,14 @@ void Chainstate::InitCoinsDB(
}
m_coins_views = std::make_unique<CoinsViews>(
- leveldb_name, cache_size_bytes, in_memory, should_wipe);
+ DBParams{
+ .path = gArgs.GetDataDirNet() / leveldb_name,
+ .cache_bytes = cache_size_bytes,
+ .memory_only = in_memory,
+ .wipe_data = should_wipe,
+ .obfuscate = true,
+ .options = [] { DBOptions options; node::ReadDatabaseArgs(gArgs, options); return options; }()},
+ [] { CoinsViewOptions options; node::ReadCoinsViewArgs(gArgs, options); return options; }());
}
void Chainstate::InitCoinsCache(size_t cache_size_bytes)
diff --git a/src/validation.h b/src/validation.h
index 7170467b00..13a59d32dd 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -408,7 +408,7 @@ public:
//! state to disk, which should not be done until the health of the database is verified.
//!
//! All arguments forwarded onto CCoinsViewDB.
- CoinsViews(fs::path ldb_name, size_t cache_size_bytes, bool in_memory, bool should_wipe);
+ CoinsViews(DBParams db_params, CoinsViewOptions options);
//! Initialize the CCoinsViewCache member.
void InitCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);