From 32169c3855ff2f5bbf62662f036d70a956d89f6b Mon Sep 17 00:00:00 2001 From: Andrew Toth Date: Sat, 21 Mar 2026 11:21:10 -0400 Subject: [PATCH] dbwrapper: accept optional testing leveldb::Env in DBParams Allow callers to inject a custom leveldb::Env via DBParams::testing_env, which takes priority over the memory_only in-memory environment. This enables fuzz harnesses to supply a deterministic environment. --- src/dbwrapper.cpp | 12 +++++++++--- src/dbwrapper.h | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index ee6419d2041..9bb85214041 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 c36864004fd..3e81a27e373 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -19,6 +19,10 @@ #include #include +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;