dbwrapper: accept optional testing leveldb::Env in DBParams
What changed, and why it matters
This change adds a new testing-only option for Bitcoin Core's internal database wrapper. It lets fuzz tests and other test code inject a fake, deterministic LevelDB environment. It does not change normal node behavior and is not a security fix or vulnerability.
No security action needed. Review as normal code-quality/test-infrastructure change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit introduces DBParams::testing_env, an optional leveldb::Env pointer. When set, it overrides the default environment and the memory_only in-memory environment. The constructor asserts that testing_env and memory_only are not both set, uses the injected env if present, and skips directory creation when a testing env is used. This is purely a test-infrastructure refactor to support deterministic fuzzing.
Changed components
src/dbwrapper.cppsrc/dbwrapper.hInspect captured patch +16 / −3
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp
index ee6419d2..9bb85214 100644
--- a/src/dbwrapper.cpp
+++ b/src/dbwrapper.cpp
@@ -224,16 +224,22 @@ CDBWrapper::CDBWrapper(const DBParams& params)
DBContext().options = GetOptions(params.cache_bytes);
DBContext().options.create_if_missing = true;
DBContext().options.max_file_size = params.max_file_size;
- if (params.memory_only) {
+ assert(!(params.testing_env && params.memory_only));
+ if (params.testing_env) {
+ DBContext().options.env = params.testing_env;
+ } else if (params.memory_only) {
DBContext().penv = leveldb::NewMemEnv(leveldb::Env::Default());
DBContext().options.env = DBContext().penv;
- } else {
+ }
+ if (!params.memory_only) {
if (params.wipe_data) {
LogInfo("Wiping LevelDB in %s", fs::PathToString(params.path));
leveldb::Status result = leveldb::DestroyDB(fs::PathToString(params.path), DBContext().options);
HandleError(result);
}
- TryCreateDirectories(params.path);
+ if (!params.testing_env) {
+ TryCreateDirectories(params.path);
+ }
LogInfo("Opening LevelDB in %s", fs::PathToString(params.path));
}
// PathToString() return value is safe to pass to leveldb open function,
diff --git a/src/dbwrapper.h b/src/dbwrapper.h
index c3686400..3e81a27e 100644
--- a/src/dbwrapper.h
+++ b/src/dbwrapper.h
@@ -19,6 +19,10 @@
#include <stdexcept>
#include <string>
+namespace leveldb {
+class Env;
+} // namespace leveldb
+
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
@@ -44,6 +48,9 @@ struct DBParams {
bool obfuscate = false;
//! Passed-through options.
DBOptions options{};
+ //! If non-null, use this as the leveldb::Env instead of the default.
+ //! Caller retains ownership.
+ leveldb::Env* testing_env = nullptr;
//! Maximum LevelDB SST file size. Larger values reduce the frequency
//! of compactions but increase their duration.
size_t max_file_size = DBWRAPPER_MAX_FILE_SIZE;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.